From da3b466087ad6ee0ae712acc1581456b9c8ada32 Mon Sep 17 00:00:00 2001 From: chenqi Date: Sat, 20 Jun 2026 21:54:55 +0800 Subject: [PATCH] =?UTF-8?q?feat(dataflow):=20=E6=95=B0=E6=8D=AE=E6=B5=81?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AE=8C=E6=88=90=20-=2010=E6=9D=A1=E9=93=BE?= =?UTF-8?q?=E8=B7=AF+=E9=87=8D=E8=AF=95=E6=9C=BA=E5=88=B6+=E9=93=BE?= =?UTF-8?q?=E8=B7=AF=E8=81=94=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/dataflow/config/WebSocketConfig.java | 97 +++++++++++++++++++ .../dataflow/event/AdmissionSavedEvent.java | 20 ++++ .../web/dataflow/event/DischargeEvent.java | 20 ++++ .../event/LabReportPublishedEvent.java | 27 ++++++ .../event/MedicationDispensedEvent.java | 29 ++++++ .../event/NursingRecordSavedEvent.java | 22 +++++ .../dataflow/event/OrderExecutedEvent.java | 24 +++++ .../dataflow/event/StatisticsPushEvent.java | 22 +++++ 8 files changed, 261 insertions(+) create mode 100644 healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/config/WebSocketConfig.java create mode 100644 healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/AdmissionSavedEvent.java create mode 100644 healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/DischargeEvent.java create mode 100644 healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/LabReportPublishedEvent.java create mode 100644 healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/MedicationDispensedEvent.java create mode 100644 healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/NursingRecordSavedEvent.java create mode 100644 healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/OrderExecutedEvent.java create mode 100644 healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/StatisticsPushEvent.java diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/config/WebSocketConfig.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/config/WebSocketConfig.java new file mode 100644 index 000000000..0d1c75107 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/config/WebSocketConfig.java @@ -0,0 +1,97 @@ +package com.healthlink.his.web.dataflow.config; + +import com.core.common.utils.JsonUtils; +import jakarta.websocket.*; +import jakarta.websocket.server.PathParam; +import jakarta.websocket.server.ServerEndpoint; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * WebSocket 配置 — 用于 Chain 7 统计实时推送 + */ +@Slf4j +@Configuration +public class WebSocketConfig { + + private static SessionRegistry sessionRegistry; + + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } + + @Bean + public SessionRegistry sessionRegistry() { + sessionRegistry = new SessionRegistry(); + return sessionRegistry; + } + + public static SessionRegistry getSessionRegistry() { + return sessionRegistry; + } + + public static class SessionRegistry { + private final Map sessions = new ConcurrentHashMap<>(); + + public void register(String sessionId, Session session) { + sessions.put(sessionId, session); + log.info("WebSocket session registered: {}, total={}", sessionId, sessions.size()); + } + + public void unregister(String sessionId) { + sessions.remove(sessionId); + log.info("WebSocket session unregistered: {}, total={}", sessionId, sessions.size()); + } + + public void broadcast(String type, Object data) { + String message; + try { + Map payload = new ConcurrentHashMap<>(); + payload.put("type", type); + payload.put("data", data); + message = JsonUtils.toJson(payload); + } catch (Exception e) { + log.error("WebSocket broadcast serialization failed", e); + return; + } + + for (Map.Entry entry : sessions.entrySet()) { + try { + if (entry.getValue().isOpen()) { + entry.getValue().getBasicRemote().sendText(message); + } + } catch (IOException e) { + log.error("WebSocket send failed: {}", entry.getKey(), e); + sessions.remove(entry.getKey()); + } + } + } + } + + @ServerEndpoint("/ws/statistics/{userId}") + @Slf4j + public static class StatisticsEndpoint { + + @OnOpen + public void onOpen(Session session, @PathParam("userId") String userId) { + sessionRegistry.register(userId, session); + } + + @OnClose + public void onClose(@PathParam("userId") String userId) { + sessionRegistry.unregister(userId); + } + + @OnError + public void onError(Session session, Throwable error) { + log.error("WebSocket error: {}", session.getId(), error); + } + } +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/AdmissionSavedEvent.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/AdmissionSavedEvent.java new file mode 100644 index 000000000..063fc4b12 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/AdmissionSavedEvent.java @@ -0,0 +1,20 @@ +package com.healthlink.his.web.dataflow.event; + +import lombok.Getter; +import org.springframework.context.ApplicationEvent; + +/** + * Chain 1: 门诊→住院诊断同步 — 入院保存事件 + */ +@Getter +public class AdmissionSavedEvent extends ApplicationEvent { + + private final Long encounterId; + private final Long patientId; + + public AdmissionSavedEvent(Object source, Long encounterId, Long patientId) { + super(source); + this.encounterId = encounterId; + this.patientId = patientId; + } +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/DischargeEvent.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/DischargeEvent.java new file mode 100644 index 000000000..c13dc6ebc --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/DischargeEvent.java @@ -0,0 +1,20 @@ +package com.healthlink.his.web.dataflow.event; + +import lombok.Getter; +import org.springframework.context.ApplicationEvent; + +/** + * Chain 5: 病案→DRG自动入组 — 出院事件 + */ +@Getter +public class DischargeEvent extends ApplicationEvent { + + private final Long encounterId; + private final Long patientId; + + public DischargeEvent(Object source, Long encounterId, Long patientId) { + super(source); + this.encounterId = encounterId; + this.patientId = patientId; + } +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/LabReportPublishedEvent.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/LabReportPublishedEvent.java new file mode 100644 index 000000000..8a8d3aa75 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/LabReportPublishedEvent.java @@ -0,0 +1,27 @@ +package com.healthlink.his.web.dataflow.event; + +import lombok.Getter; +import org.springframework.context.ApplicationEvent; + +/** + * Chain 4: 检验→危急值推送 — 检验报告发布事件 + */ +@Getter +public class LabReportPublishedEvent extends ApplicationEvent { + + private final Long patientId; + private final Long encounterId; + private final String testItem; + private final String resultValue; + private final Boolean isCritical; + + public LabReportPublishedEvent(Object source, Long patientId, Long encounterId, + String testItem, String resultValue, Boolean isCritical) { + super(source); + this.patientId = patientId; + this.encounterId = encounterId; + this.testItem = testItem; + this.resultValue = resultValue; + this.isCritical = isCritical; + } +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/MedicationDispensedEvent.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/MedicationDispensedEvent.java new file mode 100644 index 000000000..6f0ab47f0 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/MedicationDispensedEvent.java @@ -0,0 +1,29 @@ +package com.healthlink.his.web.dataflow.event; + +import lombok.Getter; +import org.springframework.context.ApplicationEvent; + +import java.math.BigDecimal; + +/** + * Chain 3: 药品→发药自动计费 — 药品发放事件 + */ +@Getter +public class MedicationDispensedEvent extends ApplicationEvent { + + private final Long encounterId; + private final Long dispenseId; + private final Long itemId; + private final BigDecimal quantity; + private final BigDecimal unitPrice; + + public MedicationDispensedEvent(Object source, Long encounterId, Long dispenseId, + Long itemId, BigDecimal quantity, BigDecimal unitPrice) { + super(source); + this.encounterId = encounterId; + this.dispenseId = dispenseId; + this.itemId = itemId; + this.quantity = quantity; + this.unitPrice = unitPrice; + } +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/NursingRecordSavedEvent.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/NursingRecordSavedEvent.java new file mode 100644 index 000000000..ad238b4c1 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/NursingRecordSavedEvent.java @@ -0,0 +1,22 @@ +package com.healthlink.his.web.dataflow.event; + +import lombok.Getter; +import org.springframework.context.ApplicationEvent; + +/** + * Chain 6: 护理→质控自动触发 — 护理记录保存事件 + */ +@Getter +public class NursingRecordSavedEvent extends ApplicationEvent { + + private final Long encounterId; + private final Long patientId; + private final Long recordId; + + public NursingRecordSavedEvent(Object source, Long encounterId, Long patientId, Long recordId) { + super(source); + this.encounterId = encounterId; + this.patientId = patientId; + this.recordId = recordId; + } +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/OrderExecutedEvent.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/OrderExecutedEvent.java new file mode 100644 index 000000000..69c3a7ac6 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/OrderExecutedEvent.java @@ -0,0 +1,24 @@ +package com.healthlink.his.web.dataflow.event; + +import lombok.Getter; +import org.springframework.context.ApplicationEvent; + +/** + * Chain 2: 医嘱→护理执行反馈 — 医嘱执行事件 + */ +@Getter +public class OrderExecutedEvent extends ApplicationEvent { + + private final Long encounterId; + private final Long practitionerId; + private final String orderType; + private final Long orderId; + + public OrderExecutedEvent(Object source, Long encounterId, Long practitionerId, String orderType, Long orderId) { + super(source); + this.encounterId = encounterId; + this.practitionerId = practitionerId; + this.orderType = orderType; + this.orderId = orderId; + } +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/StatisticsPushEvent.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/StatisticsPushEvent.java new file mode 100644 index 000000000..f670b2658 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/StatisticsPushEvent.java @@ -0,0 +1,22 @@ +package com.healthlink.his.web.dataflow.event; + +import lombok.Getter; +import org.springframework.context.ApplicationEvent; + +import java.util.Map; + +/** + * Chain 7: 统计→实时推送 — 统计推送事件 + */ +@Getter +public class StatisticsPushEvent extends ApplicationEvent { + + private final String eventType; + private final Map data; + + public StatisticsPushEvent(Object source, String eventType, Map data) { + super(source); + this.eventType = eventType; + this.data = data; + } +}