From 116734f1f8e5166840be770f9e8c37a4edc260c8 Mon Sep 17 00:00:00 2001 From: Ranyunqiao <2499115710@qq.com> Date: Tue, 12 May 2026 17:27:25 +0800 Subject: [PATCH] 413 460 513 514 --- .../dto/InfectiousDiseaseReportDto.java | 2 + .../impl/ProductTransferAppServiceImpl.java | 58 ++++++++++++ .../ReportManagement/index.vue | 3 +- .../components/diagnosis/diagnosis.vue | 84 ++++++++++++++--- .../infectiousDiseaseReportDialog.vue | 28 +++--- .../prescription/prescriptionlist.vue | 16 ++-- .../doctorstation/mycardmanagement/index.vue | 91 +++---------------- .../components/prescriptionList.vue | 10 +- .../transferManagent/batchTransfer/index.vue | 18 +--- .../transferManagent/index.vue | 10 -- 10 files changed, 183 insertions(+), 137 deletions(-) diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/InfectiousDiseaseReportDto.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/InfectiousDiseaseReportDto.java index f09c4581..f3ae3f95 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/InfectiousDiseaseReportDto.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/InfectiousDiseaseReportDto.java @@ -1,5 +1,6 @@ package com.openhis.web.doctorstation.dto; +import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import lombok.Data; @@ -55,6 +56,7 @@ public class InfectiousDiseaseReportDto { private String sex; /** 出生日期 */ + @JsonFormat(pattern = "yyyy-MM-dd") private Date birthday; /** 实足年龄 */ diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inventorymanage/appservice/impl/ProductTransferAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inventorymanage/appservice/impl/ProductTransferAppServiceImpl.java index be5c9602..cb68c678 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inventorymanage/appservice/impl/ProductTransferAppServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inventorymanage/appservice/impl/ProductTransferAppServiceImpl.java @@ -17,6 +17,9 @@ import com.openhis.common.constant.PromptMsgConstant; import com.openhis.common.enums.*; import com.openhis.common.utils.EnumUtils; import com.openhis.common.utils.HisQueryUtils; +import com.core.common.utils.SecurityUtils; +import com.openhis.workflow.domain.InventoryItem; +import com.openhis.workflow.service.IInventoryItemService; import com.openhis.web.basedatamanage.dto.LocationDto; import com.openhis.web.common.dto.UnitDto; import com.openhis.web.inventorymanage.appservice.IProductTransferAppService; @@ -57,6 +60,9 @@ public class ProductTransferAppServiceImpl implements IProductTransferAppService @Autowired private IPractitionerService practitionerService; + @Autowired + private IInventoryItemService inventoryItemService; + /** * 商品调拨页面初始化 * @@ -196,6 +202,23 @@ public class ProductTransferAppServiceImpl implements IProductTransferAppService @Override public R addOrEditBatchTransferReceipt(List productTransferDtoList, Boolean flag) { + // 校验调拨数量:必须 > 0 且不超过源库存数量(从数据库查实时库存) + Integer tenantId = SecurityUtils.getLoginUser().getTenantId(); + for (ProductTransferDto dto : productTransferDtoList) { + if (dto.getItemQuantity() == null || dto.getItemQuantity().compareTo(java.math.BigDecimal.ZERO) <= 0) { + return R.fail("调拨数量必须大于0"); + } + // 查询该药品在源仓库的实时库存总量 + List inventoryList = inventoryItemService.selectInventoryByItemId( + dto.getItemId(), dto.getLotNumber(), dto.getSourceLocationId(), tenantId); + java.math.BigDecimal actualStock = inventoryList.stream() + .map(InventoryItem::getQuantity) + .reduce(java.math.BigDecimal.ZERO, java.math.BigDecimal::add); + if (dto.getItemQuantity().compareTo(actualStock) > 0) { + return R.fail("调拨数量不可超出源库存数量(当前库存:" + actualStock + ")"); + } + } + List idList = new ArrayList<>(); if (flag) { // 批量保存按钮 @@ -309,6 +332,22 @@ public class ProductTransferAppServiceImpl implements IProductTransferAppService @Override public R addOrEditTransferReceipt(List productTransferDtoList) { + // 校验调拨数量:必须 > 0 且不超过源库存数量(从数据库查实时库存) + Integer tenantId = SecurityUtils.getLoginUser().getTenantId(); + for (ProductTransferDto dto : productTransferDtoList) { + if (dto.getItemQuantity() == null || dto.getItemQuantity().compareTo(java.math.BigDecimal.ZERO) <= 0) { + return R.fail("调拨数量必须大于0"); + } + List inventoryList = inventoryItemService.selectInventoryByItemId( + dto.getItemId(), dto.getLotNumber(), dto.getSourceLocationId(), tenantId); + java.math.BigDecimal actualStock = inventoryList.stream() + .map(InventoryItem::getQuantity) + .reduce(java.math.BigDecimal.ZERO, java.math.BigDecimal::add); + if (dto.getItemQuantity().compareTo(actualStock) > 0) { + return R.fail("调拨数量不可超出源库存数量(当前库存:" + actualStock + ")"); + } + } + List idList = new ArrayList<>(); // 单据号取得 @@ -380,6 +419,25 @@ public class ProductTransferAppServiceImpl implements IProductTransferAppService */ @Override public R submitApproval(String busNo) { + // 提交前再次校验调拨数量(从数据库查实时库存) + List requestList = supplyRequestService.getSupplyByBusNo(busNo); + if (requestList != null && !requestList.isEmpty()) { + Integer tenantId = SecurityUtils.getLoginUser().getTenantId(); + for (SupplyRequest request : requestList) { + if (request.getItemQuantity() == null || request.getItemQuantity().compareTo(java.math.BigDecimal.ZERO) <= 0) { + return R.fail("调拨数量必须大于0,请检查后重新保存"); + } + // 查询该药品在源仓库的实时库存总量 + List inventoryList = inventoryItemService.selectInventoryByItemId( + request.getItemId(), request.getLotNumber(), request.getSourceLocationId(), tenantId); + java.math.BigDecimal actualStock = inventoryList.stream() + .map(InventoryItem::getQuantity) + .reduce(java.math.BigDecimal.ZERO, java.math.BigDecimal::add); + if (request.getItemQuantity().compareTo(actualStock) > 0) { + return R.fail("调拨数量不可超出源库存数量(当前库存:" + actualStock + "),请检查后重新保存"); + } + } + } // 单据提交审核 boolean result = supplyRequestService.submitApproval(busNo); return result ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null)) diff --git a/openhis-ui-vue3/src/views/diseaseReportManagement/ReportManagement/index.vue b/openhis-ui-vue3/src/views/diseaseReportManagement/ReportManagement/index.vue index 510cb70b..d74d56eb 100755 --- a/openhis-ui-vue3/src/views/diseaseReportManagement/ReportManagement/index.vue +++ b/openhis-ui-vue3/src/views/diseaseReportManagement/ReportManagement/index.vue @@ -519,9 +519,10 @@ > - + @@ -476,9 +476,9 @@ @@ -510,6 +510,7 @@ const DISEASE_NAMES = { }; const dialogVisible = ref(false); +const dialogReadOnly = ref(false); const formRef = ref(null); // 保存按钮加载状态,防止重复提交 const submitLoading = ref(false); @@ -1037,8 +1038,9 @@ function resetAddressSelector() { * 以只读详情方式打开报卡弹窗,供报卡管理等页面复用医生站报卡样式。 * @param {Object} reportData - 报卡详情数据 */ -function showReport(reportData = {}) { +function showReport(reportData = {}, readOnly = true) { dialogVisible.value = true; + dialogReadOnly.value = readOnly; resetAddressSelector(); initProvinceOptions(); @@ -1205,6 +1207,7 @@ function calculateAge() { */ async function show(diagnosisData) { dialogVisible.value = true; + dialogReadOnly.value = false; // 重置地址选择器状态 resetAddressSelector(); @@ -1238,14 +1241,13 @@ async function show(diagnosisData) { let cardNo = ''; try { const res = await getNextCardNo(orgCode); - if (res.code === 200 && res.data) { + if (res.code === 200 && res.data && res.data.length >= 12) { cardNo = res.data; - } else { - cardNo = 'TEMP_' + Date.now(); } + // API失败或返回不合规时保持为空字符串,由用户手动填写或后端自动生成 } catch (err) { console.error('获取卡片编号失败:', err); - cardNo = 'TEMP_' + Date.now(); + // 保持为空,不使用不合规的临时值 } form.value = { @@ -1424,9 +1426,9 @@ async function buildSubmitData() { function validateFormManually() { const errors = []; - // 卡片编号验证(可选,但如果填写了必须是12位) - if (form.value.cardNo && form.value.cardNo.length !== 12) { - errors.push('卡片编号必须为12位'); + // 卡片编号验证(至少12位,后端自动生成16位编号) + if (form.value.cardNo && form.value.cardNo.length < 12) { + errors.push('卡片编号至少12位'); } // 身份证号验证 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 07d88f1a..2c4cabc2 100755 --- a/openhis-ui-vue3/src/views/doctorstation/components/prescription/prescriptionlist.vue +++ b/openhis-ui-vue3/src/views/doctorstation/components/prescription/prescriptionlist.vue @@ -2495,11 +2495,13 @@ function handleSave(prescriptionId) { // 🔧 BugFix#318: 从 parsedContent 提取标准医嘱字段,排除手术特有字段 const standardFields = [ - 'accountId', 'chargeItemId', 'conditionDefinitionId', 'conditionId', - 'contentJson', 'definitionDetailId', 'definitionId', 'diagnosisName', - 'dosageInstruction', 'effectiveOrgId', 'encounterDiagnosisId', - 'encounterId', 'lotNumber', 'patientId', 'practitionerId', - 'prescriptionNo', 'skinTestFlag', 'unitPrice', 'volume', 'ybClassEnum' + 'accountId', 'chargeItemId', 'conditionDefinitionId', 'conditionId', + 'contentJson', 'definitionDetailId', 'definitionId', 'diagnosisName', + 'dosageInstruction', 'effectiveOrgId', 'encounterDiagnosisId', + 'encounterId', 'lotNumber', 'patientId', 'practitionerId', + 'prescriptionNo', 'skinTestFlag', 'unitPrice', 'volume', 'ybClassEnum', + // 🔧 Bug Fix: 添加 therapyEnum 字段(医嘱类型:1=长期, 2=临时) + 'therapyEnum' ]; let filteredContent = {}; standardFields.forEach(field => { @@ -3143,7 +3145,9 @@ function handleSaveBatch(prescriptionId) { // 🔧 Bug Fix: 添加 definitionId 和 definitionDetailId 字段 'definitionId', 'definitionDetailId', // 🔧 Bug Fix: 添加 categoryEnum 字段(耗材必填) - 'categoryEnum' + 'categoryEnum', + // 🔧 Bug Fix: 添加 therapyEnum 字段(医嘱类型:1=长期, 2=临时) + 'therapyEnum' ]; let filteredItem = {}; standardItemFields.forEach(field => { diff --git a/openhis-ui-vue3/src/views/doctorstation/mycardmanagement/index.vue b/openhis-ui-vue3/src/views/doctorstation/mycardmanagement/index.vue index 1c4ffa49..9f997032 100755 --- a/openhis-ui-vue3/src/views/doctorstation/mycardmanagement/index.vue +++ b/openhis-ui-vue3/src/views/doctorstation/mycardmanagement/index.vue @@ -151,23 +151,12 @@ - - - - + @@ -175,7 +164,7 @@ import { ref, reactive, onMounted, onActivated, onBeforeUnmount, nextTick, computed } from 'vue'; import { ElMessage, ElMessageBox } from 'element-plus'; import { DataAnalysis, Warning, CircleCheck, Check, RefreshRight } from '@element-plus/icons-vue'; -import InfectiousReport from '../components/infectiousReport/index.vue'; +import InfectiousDiseaseReportDialog from '../components/diagnosis/infectiousDiseaseReportDialog.vue'; import { getDoctorCardStatistics, getDoctorCardList, @@ -185,7 +174,6 @@ import { batchDeleteCards, exportCardToWord, getCardDetail, - updateDoctorCard, } from './api'; const loading = ref(false); @@ -211,7 +199,7 @@ const queryParams = reactive({ const detailVisible = ref(false); const detailMode = ref('view'); -const currentCard = ref({}); +const infectiousDiseaseReportRef = ref(null); // 计算表格高度:根据视口高度动态调整 const tableHeight = computed(() => { @@ -327,9 +315,11 @@ async function handleView(row) { try { const res = await getCardDetail(row.cardNo); if (res.code === 200) { - currentCard.value = res.data || {}; detailMode.value = 'view'; detailVisible.value = true; + nextTick(() => { + infectiousDiseaseReportRef.value?.showReport(res.data || {}); + }); } } catch (error) { ElMessage.error('获取详情失败'); @@ -340,57 +330,17 @@ async function handleEdit(row) { try { const res = await getCardDetail(row.cardNo); if (res.code === 200) { - currentCard.value = res.data || {}; detailMode.value = 'edit'; detailVisible.value = true; + nextTick(() => { + infectiousDiseaseReportRef.value?.showReport(res.data || {}, false); + }); } } catch (error) { ElMessage.error('获取详情失败'); } } -async function handleSaveEdit(submitData) { - // submitData 来自 InfectiousReport 组件的 submit-edit 事件 - try { - const updateData = { - cardNo: submitData.cardNo, - phone: submitData.phone, - contactPhone: submitData.contactPhone, - onsetDate: submitData.onsetDate, - diagDate: submitData.diagDate, - diseaseCode: submitData.diseaseCode, - diseaseType: submitData.diseaseType, - otherDisease: submitData.otherDisease, - caseClass: submitData.caseClass, - occupation: submitData.occupation, - patientBelong: submitData.patientBelong, - addressProv: submitData.addressProv, - addressCity: submitData.addressCity, - addressCounty: submitData.addressCounty, - addressTown: submitData.addressTown, - addressVillage: submitData.addressVillage, - addressHouse: submitData.addressHouse, - workplace: submitData.workplace, - parentName: submitData.parentName, - deathDate: submitData.deathDate, - correctName: submitData.correctName, - withdrawReason: submitData.withdrawReason, - remark: submitData.remark, - }; - - const res = await updateDoctorCard(updateData); - if (res.code === 200) { - ElMessage.success('保存成功'); - detailVisible.value = false; - getList(); - } else { - ElMessage.error(res.msg || '保存失败'); - } - } catch (error) { - ElMessage.error('保存失败:' + (error.message || '网络错误')); - } -} - async function handleSubmit(row) { try { await ElMessageBox.confirm('确认提交该报卡?', '提示', { @@ -800,17 +750,4 @@ function handleResize() { margin-left: 0; } } - -/* 报卡详情弹窗 */ -:deep(.card-detail-dialog .el-dialog__body) { - padding: 0; - overflow: hidden; -} - -:deep(.card-detail-dialog .infectious-report-container) { - padding: 16px; - height: auto; - max-height: 70vh; - overflow-y: auto; -} \ No newline at end of file diff --git a/openhis-ui-vue3/src/views/inpatientNurse/medicalOrderProofread/components/prescriptionList.vue b/openhis-ui-vue3/src/views/inpatientNurse/medicalOrderProofread/components/prescriptionList.vue index f9596f1c..b9fd624d 100755 --- a/openhis-ui-vue3/src/views/inpatientNurse/medicalOrderProofread/components/prescriptionList.vue +++ b/openhis-ui-vue3/src/views/inpatientNurse/medicalOrderProofread/components/prescriptionList.vue @@ -11,9 +11,9 @@ >
- 全部 - 长期 - 临时 + 全部 + 长期 + 临时 查询 @@ -159,7 +159,7 @@ import {formatDateStr} from '@/utils/index'; const activeNames = ref([]); const prescriptionList = ref([]); const deadline = ref(formatDateStr(new Date(), 'YYYY-MM-DD') + ' 23:59:59'); -const type = ref(1); +const type = ref(null); const { proxy } = getCurrentInstance(); const loading = ref(false); const chooseAll = ref(false); @@ -181,7 +181,7 @@ function handleGetPrescription() { getPrescriptionList({ encounterIds: encounterIds, requestStatus: props.requestStatus, - ...(type.value !== undefined ? { therapyEnum: type.value } : {}), + ...(type.value != null ? { therapyEnum: type.value } : {}), pageSize: 10000, pageNo: 1, }).then((res) => { diff --git a/openhis-ui-vue3/src/views/medicationmanagement/transferManagent/batchTransfer/index.vue b/openhis-ui-vue3/src/views/medicationmanagement/transferManagent/batchTransfer/index.vue index 22943b93..b173b299 100755 --- a/openhis-ui-vue3/src/views/medicationmanagement/transferManagent/batchTransfer/index.vue +++ b/openhis-ui-vue3/src/views/medicationmanagement/transferManagent/batchTransfer/index.vue @@ -744,11 +744,7 @@ function handleSubmitApproval() { } else { submitApproval(receiptHeaderForm.busNo).then((response) => { proxy.$modal.msgSuccess('提交审批成功'); - // proxy.$tab.closePage(route).then(({ visitedViews }) => { // 关闭当前页 - // toLastView(visitedViews, route) - // }) tagsViewStore.delView(router.currentRoute.value); - // 跳转到调拨管理页面 router.replace({ path: 'transferManagentList' }); }); } @@ -871,7 +867,6 @@ function handleUnitCodeChange(row, index, value) { } function handleItemQuantityChange(row, value) { - debugger; let quantityTemp = ''; // 转换成小单位的临时变量 做校验 // 大单位情况 if (row.unitCodeMap[row.unitCode] == 'unit') { @@ -882,12 +877,6 @@ function handleItemQuantityChange(row, value) { row.itemQuantity = value; quantityTemp = value; } - if (row.totalSourceQuantity < quantityTemp) { - proxy.$modal.msgWarning('调拨数量不可超出源库存数量'); - row.itemQuantity = 0; - row.itemQuantityDisplay = 0; - return; - } row.totalPrice = ((row.price * quantityTemp) / row.partPercent).toFixed(2); // 更新总数据中对应的记录 const totalIndex = totalIncentoryInfoList.value.findIndex((item) => item.id === row.id); @@ -918,11 +907,12 @@ function remakeBlur(row, index) { editBatchTransfer(index); } function handleSave() { - const invalidRow = totalIncentoryInfoList.value.find( + // 校验单价 + const invalidPriceRow = totalIncentoryInfoList.value.find( (row) => !row.price || row.price <= 0 ); - if (invalidRow) { - proxy.$message.warning('调拨单价不能为空或为0,请检查!'); + if (invalidPriceRow) { + proxy.$modal.msgError('调拨单价不能为空或为0,请检查!'); return; } addTransferProductBatch(totalIncentoryInfoList.value).then((res) => { diff --git a/openhis-ui-vue3/src/views/medicationmanagement/transferManagent/transferManagent/index.vue b/openhis-ui-vue3/src/views/medicationmanagement/transferManagent/transferManagent/index.vue index 010c0e11..bbed6fb1 100755 --- a/openhis-ui-vue3/src/views/medicationmanagement/transferManagent/transferManagent/index.vue +++ b/openhis-ui-vue3/src/views/medicationmanagement/transferManagent/transferManagent/index.vue @@ -970,12 +970,6 @@ function handleItemQuantityChange(row, value) { row.itemQuantity = value; quantityTemp = value; } - if (row.totalSourceQuantity < quantityTemp) { - proxy.$modal.msgWarning('调拨数量不可超出源库存数量'); - row.itemQuantity = 0; - row.itemQuantityDisplay = 0; - return; - } row.totalPrice = ((row.price * quantityTemp) / row.partPercent).toFixed(2); } @@ -1022,11 +1016,7 @@ function handleSubmitApproval() { } else { submitApproval(receiptHeaderForm.busNo).then((response) => { proxy.$modal.msgSuccess('提交审批成功'); - // proxy.$tab.closePage(route).then(({ visitedViews }) => { // 关闭当前页 - // toLastView(visitedViews, route) - // }) tagsViewStore.delView(router.currentRoute.value); - // 跳转到调拨管理页面 router.replace({ path: 'transferManagentList' }); store.clearCurrentDataDB(); });