88 分诊排队管理-》科室叫号显示屏 表triage_queue_item中添加了联合索引queue_date,organization_id,tenant_id,queue_order。添加了room_no,practitioner_id字段。新增的实体类刚刚没提交
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package com.openhis.web.triageandqueuemanage.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 叫号显示屏响应DTO
|
||||
*/
|
||||
@Data
|
||||
public class CallNumberDisplayResp {
|
||||
/** 科室名称 */
|
||||
private String departmentName;
|
||||
|
||||
/** 当前叫号信息 */
|
||||
private CurrentCallInfo currentCall;
|
||||
|
||||
/** 等候患者列表(按医生分组) */
|
||||
private List<DoctorGroup> waitingList;
|
||||
|
||||
/** 等待总人数 */
|
||||
private Integer waitingCount;
|
||||
|
||||
/**
|
||||
* 当前叫号信息
|
||||
*/
|
||||
@Data
|
||||
public static class CurrentCallInfo {
|
||||
/** 排队号 */
|
||||
private Integer number;
|
||||
/** 患者姓名(脱敏) */
|
||||
private String name;
|
||||
/** 诊室号 */
|
||||
private String room;
|
||||
/** 医生姓名 */
|
||||
private String doctor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 医生分组信息
|
||||
*/
|
||||
@Data
|
||||
public static class DoctorGroup {
|
||||
/** 医生姓名 */
|
||||
private String doctorName;
|
||||
/** 诊室号 */
|
||||
private String roomNo;
|
||||
/** 该医生的患者列表 */
|
||||
private List<PatientInfo> patients;
|
||||
}
|
||||
|
||||
/**
|
||||
* 患者信息
|
||||
*/
|
||||
@Data
|
||||
public static class PatientInfo {
|
||||
/** 队列项ID */
|
||||
private Long id;
|
||||
/** 患者姓名(脱敏) */
|
||||
private String name;
|
||||
/** 状态:CALLING=就诊中,WAITING=等待 */
|
||||
private String status;
|
||||
/** 排队号 */
|
||||
private Integer queueOrder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.openhis.web.triageandqueuemanage.sse;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
/**
|
||||
* 叫号显示屏 SSE 管理器(服务端推送)
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CallNumberSseManager {
|
||||
|
||||
private static final long NO_TIMEOUT = 0L;
|
||||
private static final Map<Long, CopyOnWriteArraySet<SseEmitter>> emitterMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 创建并注册一个 SSE 连接(按科室分组保存)
|
||||
*/
|
||||
public SseEmitter addEmitter(Long organizationId) {
|
||||
SseEmitter emitter = new SseEmitter(NO_TIMEOUT);
|
||||
emitterMap.computeIfAbsent(organizationId, k -> new CopyOnWriteArraySet<>()).add(emitter);
|
||||
|
||||
emitter.onCompletion(() -> removeEmitter(organizationId, emitter));
|
||||
emitter.onTimeout(() -> removeEmitter(organizationId, emitter));
|
||||
emitter.onError((ex) -> removeEmitter(organizationId, emitter));
|
||||
|
||||
log.info("SSE连接建立:科室ID={}, 当前该科室连接数={}",
|
||||
organizationId, emitterMap.get(organizationId).size());
|
||||
return emitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 向指定科室的所有 SSE 连接推送消息
|
||||
*/
|
||||
public void pushToOrganization(Long organizationId, Object message) {
|
||||
CopyOnWriteArraySet<SseEmitter> emitters = emitterMap.get(organizationId);
|
||||
if (emitters == null || emitters.isEmpty()) {
|
||||
log.debug("科室{}没有SSE连接,跳过推送", organizationId);
|
||||
return;
|
||||
}
|
||||
|
||||
for (SseEmitter emitter : emitters) {
|
||||
if (!sendToEmitter(emitter, message)) {
|
||||
removeEmitter(organizationId, emitter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 向单个 SSE 连接发送数据
|
||||
*/
|
||||
public boolean sendToEmitter(SseEmitter emitter, Object data) {
|
||||
try {
|
||||
emitter.send(SseEmitter.event().data(data));
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
log.warn("SSE推送失败:{}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 断开或异常时移除 SSE 连接
|
||||
*/
|
||||
private void removeEmitter(Long organizationId, SseEmitter emitter) {
|
||||
CopyOnWriteArraySet<SseEmitter> emitters = emitterMap.get(organizationId);
|
||||
if (emitters != null) {
|
||||
emitters.remove(emitter);
|
||||
if (emitters.isEmpty()) {
|
||||
emitterMap.remove(organizationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user