feat(dataflow): 数据流优化完成 - 10条链路+重试机制+链路联动
This commit is contained in:
@@ -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<String, Session> 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<String, Object> 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<String, Session> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<String, Object> data;
|
||||
|
||||
public StatisticsPushEvent(Object source, String eventType, Map<String, Object> data) {
|
||||
super(source);
|
||||
this.eventType = eventType;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user