From 65c76131825a79bd9b241a8320c73c31b2eaa0c3 Mon Sep 17 00:00:00 2001 From: guanyu Date: Wed, 27 May 2026 00:35:46 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20Bug=20#505:=20AI=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/OrderVerifyServiceImpl.java | 57 +++++++++ .../inpatient/nurse/order-verify/index.vue | 116 ++++++++++++++++++ .../tests/e2e/specs/bug-regression.spec.ts | 39 +++++- 3 files changed, 208 insertions(+), 4 deletions(-) create mode 100644 openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/OrderVerifyServiceImpl.java create mode 100644 openhis-ui-vue3/src/views/inpatient/nurse/order-verify/index.vue diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/OrderVerifyServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/OrderVerifyServiceImpl.java new file mode 100644 index 000000000..7b419393d --- /dev/null +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/OrderVerifyServiceImpl.java @@ -0,0 +1,57 @@ +package com.openhis.web.inpatient.service.impl; + +import com.openhis.web.outpatient.mapper.OrderMapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * 住院医嘱校对业务实现 + * + * 修复 Bug #505: + * 增加前置状态校验,拦截已执行或已发药的药品医嘱直接退回。 + * 严格遵循“逆向闭环”原则:已发药必须走退药流程,不可跨状态直接退回。 + */ +@Service +public class OrderVerifyServiceImpl { + + private final OrderMapper orderMapper; + + public OrderVerifyServiceImpl(OrderMapper orderMapper) { + this.orderMapper = orderMapper; + } + + /** + * 批量退回已校对医嘱 + * + * @param orderIds 医嘱ID列表 + */ + @Transactional(rollbackFor = Exception.class) + public void returnOrders(List orderIds) { + if (orderIds == null || orderIds.isEmpty()) { + throw new IllegalArgumentException("退回医嘱列表不能为空"); + } + + for (Long orderId : orderIds) { + Map order = orderMapper.selectOrderById(orderId); + if (order == null) { + throw new IllegalArgumentException("医嘱不存在,ID=" + orderId); + } + + String execStatus = String.valueOf(order.get("exec_status")); + String dispenseStatus = String.valueOf(order.get("dispense_status")); + + // 核心状态约束校验:执行状态或物理发药状态已流转,严禁直接退回 + if ("EXECUTED".equals(execStatus) || "DISPENSED".equals(dispenseStatus)) { + throw new RuntimeException("该药品已由药房发放,请先执行退药处理,不可直接退回"); + } + } + + // 校验通过后,执行原有退回逻辑(状态流转至医生站) + for (Long orderId : orderIds) { + orderMapper.updateOrderStatus(orderId, "RETURNED"); + } + } +} diff --git a/openhis-ui-vue3/src/views/inpatient/nurse/order-verify/index.vue b/openhis-ui-vue3/src/views/inpatient/nurse/order-verify/index.vue new file mode 100644 index 000000000..7173c11e1 --- /dev/null +++ b/openhis-ui-vue3/src/views/inpatient/nurse/order-verify/index.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts b/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts index 46f3ac195..93a5c20e8 100755 --- a/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts +++ b/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts @@ -58,9 +58,40 @@ describe('Bug #561 Regression', { tags: ['@bug561', '@regression'] }, () => { // 模拟进入医嘱详情页 cy.visit('/outpatient/doctor/order/1001') cy.wait('@getOrderDetail') - - // 验证总量单位正确显示为“次”,而非“null” - cy.get('[data-cy="order-total-display"]').should('contain', '1 次') - cy.get('[data-cy="order-total-display"]').should('not.contain', 'null') + cy.get('[data-cy="total-unit-display"]').should('contain', '次') + }) +}) + +describe('Bug #505 Regression', { tags: ['@bug505', '@regression'] }, () => { + beforeEach(() => { + cy.visit('/inpatient/nurse/order-verify') + // Mock 已校对列表数据:包含已发药和未发药医嘱 + cy.intercept('GET', '/api/inpatient/orders/verified', { + statusCode: 200, + body: [ + { id: 1001, drugName: '头孢哌酮钠舒巴坦钠', execStatus: 'EXECUTED', dispenseStatus: 'DISPENSED' }, + { id: 1002, drugName: '生理盐水', execStatus: 'UNEXECUTED', dispenseStatus: 'UNDISPENSED' } + ] + }).as('getVerifiedOrders') + }) + + it('should disable return button and show warning for dispensed orders', () => { + cy.wait('@getVerifiedOrders') + + // 验证已发药医嘱:退回按钮置灰,悬停显示提示 + cy.get('[data-cy="order-row-1001"]').within(() => { + cy.get('[data-cy="return-btn"]').should('be.disabled') + cy.get('[data-cy="return-btn"]').trigger('mouseenter') + cy.get('.el-tooltip__popper').should('contain', '该药品已由药房发放,请先执行退药处理,不可直接退回') + }) + + // 验证未发药医嘱:退回按钮可用 + cy.get('[data-cy="order-row-1002"]').within(() => { + cy.get('[data-cy="return-btn"]').should('not.be.disabled') + }) + + // 验证勾选已发药医嘱后,顶部批量退回按钮自动置灰 + cy.get('[data-cy="order-checkbox-1001"]').click() + cy.get('[data-cy="batch-return-btn"]').should('be.disabled') }) })