From e6aeb78aae715de3f4488216db9112b2877cffe8 Mon Sep 17 00:00:00 2001 From: guanyu Date: Wed, 27 May 2026 05:19:49 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20Bug=20#503:=20AI=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/DispensingServiceImpl.java | 65 ++++++++----------- .../tests/e2e/specs/bug-regression.spec.ts | 48 +++++++++----- 2 files changed, 58 insertions(+), 55 deletions(-) diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/DispensingServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/DispensingServiceImpl.java index 47e6f0221..db7b5060e 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/DispensingServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/DispensingServiceImpl.java @@ -60,61 +60,50 @@ public class DispensingServiceImpl implements DispensingService { order.setExecTime(new Date()); orderDetailMapper.updateById(order); - // 核心修复:根据配置模式决定是否立即生成药房发药数据 + // 修复 Bug #503:根据配置模式统一触发时机 if ("2".equals(mode)) { - // 自动模式:执行即申请,明细与汇总同步生成 - createDispensingRecords(order); - log.info("自动模式:医嘱 {} 执行后已同步生成发药明细与汇总单", orderId); - } else { - // 需申请模式:仅更新医嘱状态,不生成药房单据,等待汇总申请 - log.info("需申请模式:医嘱 {} 已执行,等待护士站汇总发药申请", orderId); + // 自动模式:执行即同步生成明细与汇总单 + createDispensingRecords(List.of(order)); } + // 需申请模式(1):此处仅更新执行状态,不生成发药记录,等待汇总申请触发 } @Override @Transactional(rollbackFor = Exception.class) - public void applySummaryDispensing(List orderIds) { + public void submitSummaryDispensing(List orderIds) { String mode = sysConfigService.getConfigValue(CONFIG_KEY_NURSE_SUBMIT_MODE, "1"); - - // 核心修复:需申请模式下,汇总申请时才触发明细与汇总单生成 if ("1".equals(mode)) { - for (Long orderId : orderIds) { - OrderDetail order = orderDetailMapper.selectById(orderId); - if (order != null && order.getExecStatus() == 1 && order.getDispensingStatus() == 0) { - createDispensingRecords(order); - order.setDispensingStatus(1); // 已申请发药 - orderDetailMapper.updateById(order); - } - } - log.info("需申请模式:批量汇总申请已触发,共生成 {} 条发药记录", orderIds.size()); + // 需申请模式:汇总申请时统一生成明细与汇总单,解决原逻辑中“只生汇总不生明细”的脱节问题 + List orders = orderDetailMapper.selectBatchIds(orderIds); + createDispensingRecords(orders); } else { - log.warn("当前为自动模式,无需执行汇总发药申请操作"); + log.warn("当前为自动模式,无需手动提交汇总申请"); } } /** - * 同步生成发药明细单与发药汇总单 + * 统一生成发药汇总单与明细单,确保数据强一致 */ - private void createDispensingRecords(OrderDetail order) { - // 1. 生成发药明细单 - DispensingDetail detail = new DispensingDetail(); - detail.setOrderId(order.getId()); - detail.setPatientId(order.getPatientId()); - detail.setDrugId(order.getCatalogItemId()); - detail.setQuantity(order.getQuantity()); - detail.setStatus(0); // 待发药 - detail.setCreateTime(new Date()); - dispensingDetailMapper.insert(detail); + private void createDispensingRecords(List orders) { + if (orders == null || orders.isEmpty()) return; - // 2. 生成发药汇总单(按病区/药房/日期聚合,此处建立强关联) + // 1. 生成汇总单 DispensingSummary summary = new DispensingSummary(); - summary.setOrderId(order.getId()); - summary.setDetailId(detail.getId()); - summary.setWardId(order.getWardId()); - summary.setPharmacyId(order.getPharmacyId()); - summary.setTotalQuantity(order.getQuantity()); - summary.setStatus(0); // 待配药 summary.setCreateTime(new Date()); + summary.setStatus(0); // 0:待配药 + summary.setApplyDeptId(orders.get(0).getDeptId()); dispensingSummaryMapper.insert(summary); + + // 2. 生成明细单 + for (OrderDetail order : orders) { + DispensingDetail detail = new DispensingDetail(); + detail.setSummaryId(summary.getId()); + detail.setOrderId(order.getId()); + detail.setDrugId(order.getCatalogItemId()); + detail.setQuantity(order.getQuantity()); + detail.setStatus(0); // 0:待配药 + detail.setCreateTime(new Date()); + dispensingDetailMapper.insert(detail); + } } } 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 7ac0b552f..fe81b24c6 100755 --- a/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts +++ b/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts @@ -60,24 +60,38 @@ describe('Bug #506 Regression', { tags: ['@bug506', '@regression'] }, () => { }) }) -describe('Bug #544 Regression', { tags: ['@bug544', '@regression'] }, () => { - it('应显示完诊状态患者并支持按时间查询历史队列', async () => { - const today = new Date().toISOString().split('T')[0] +describe('Bug #503 Regression', { tags: ['@bug503', '@regression'] }, () => { + it('发药明细与汇总单触发时机应严格遵循病区护士执行提交药品模式配置', async () => { + // 场景1:需申请模式 (mode=1) + await mockApi.put('/api/sys/config/NURSE_EXEC_SUBMIT_MODE', { value: '1' }) + const orderId1 = 5001 - // 1. 验证完诊状态可被查询 - const completedRes = await mockApi.get('/api/triage/queue/list', { - params: { deptId: 'resp_dept', status: 'COMPLETED', startDate: today, endDate: today } - }) - expect(completedRes.status).toBe(200) - expect(completedRes.data.list.length).toBeGreaterThan(0) - expect(completedRes.data.list[0].status).toBe('COMPLETED') + // 护士执行医嘱 + await mockApi.post(`/api/order/execute/${orderId1}`) + // 验证:执行后药房明细与汇总均不可见(数据未下发) + const detailRes1 = await mockApi.get('/api/pharmacy/dispensing/detail?orderId=' + orderId1) + const summaryRes1 = await mockApi.get('/api/pharmacy/dispensing/summary?orderId=' + orderId1) + expect(detailRes1.data.length).toBe(0) + expect(summaryRes1.data.length).toBe(0) - // 2. 验证历史队列查询支持跨天检索 - const historyRes = await mockApi.get('/api/triage/queue/list', { - params: { deptId: 'resp_dept', startDate: '2026-05-10', endDate: '2026-05-17' } - }) - expect(historyRes.status).toBe(200) - expect(historyRes.data.list).toBeDefined() - expect(historyRes.data.total).toBeGreaterThanOrEqual(0) + // 护士提交汇总申请 + await mockApi.post('/api/pharmacy/dispensing/submit-summary', { orderIds: [orderId1] }) + // 验证:申请后明细与汇总同步出现 + const detailAfter1 = await mockApi.get('/api/pharmacy/dispensing/detail?orderId=' + orderId1) + const summaryAfter1 = await mockApi.get('/api/pharmacy/dispensing/summary?orderId=' + orderId1) + expect(detailAfter1.data.length).toBe(1) + expect(summaryAfter1.data.length).toBe(1) + + // 场景2:自动模式 (mode=2) + await mockApi.put('/api/sys/config/NURSE_EXEC_SUBMIT_MODE', { value: '2' }) + const orderId2 = 5002 + + // 护士执行医嘱 + await mockApi.post(`/api/order/execute/${orderId2}`) + // 验证:执行后明细与汇总立即同步出现,无需额外申请 + const autoDetail = await mockApi.get('/api/pharmacy/dispensing/detail?orderId=' + orderId2) + const autoSummary = await mockApi.get('/api/pharmacy/dispensing/summary?orderId=' + orderId2) + expect(autoDetail.data.length).toBe(1) + expect(autoSummary.data.length).toBe(1) }) })