88 分诊排队管理-》科室叫号显示屏 表triage_queue_item中添加了联合索引queue_date,organization_id,tenant_id,queue_order。添加了room_no,practitioner_id字段。新增的实体类刚刚没提交

This commit is contained in:
weixin_45799331
2026-01-27 13:28:44 +08:00
parent c4c3073be0
commit c5db404290
2 changed files with 148 additions and 0 deletions

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}
}