sse实时开发

This commit is contained in:
weixin_45799331
2026-01-27 13:31:03 +08:00
parent c5db404290
commit b0f2eabf6b
5 changed files with 96 additions and 72 deletions

View File

@@ -15,7 +15,7 @@ import com.openhis.web.triageandqueuemanage.dto.TriageQueueActionReq;
import com.openhis.web.triageandqueuemanage.dto.TriageQueueAddReq;
import com.openhis.web.triageandqueuemanage.dto.TriageQueueAdjustReq;
import com.openhis.web.triageandqueuemanage.dto.TriageQueueEncounterItem;
import com.openhis.web.triageandqueuemanage.websocket.CallNumberWebSocket;
import com.openhis.web.triageandqueuemanage.sse.CallNumberSseManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -36,6 +36,9 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
@Resource
private TriageQueueItemService triageQueueItemService;
@Resource
private CallNumberSseManager callNumberSseManager;
@Resource
private TriageCandidateExclusionService triageCandidateExclusionService;
@@ -242,7 +245,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
selected.setStatus(STATUS_CALLING).setUpdateTime(LocalDateTime.now());
triageQueueItemService.updateById(selected);
// ✅ 叫号后推送 WebSocket 消息
// ✅ 叫号后推送 SSE 消息(实时通知显示屏刷新)
pushDisplayUpdate(selected.getOrganizationId(), selected.getQueueDate(), selected.getTenantId());
return R.ok(true);
@@ -329,7 +332,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
recalcOrders(actualOrgId, null);
// ✅ 完成后推送 WebSocket 消息
// ✅ 完成后推送 SSE 消息(实时通知显示屏刷新)
pushDisplayUpdate(actualOrgId, calling.getQueueDate(), tenantId);
return R.ok(true);
@@ -425,7 +428,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
recalcOrders(actualOrgId, null);
// ✅ 过号重排后推送 WebSocket 消息
// ✅ 过号重排后推送 SSE 消息(实时通知显示屏刷新)
pushDisplayUpdate(actualOrgId, calling.getQueueDate(), tenantId);
return R.ok(true);
@@ -714,7 +717,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
}
/**
* 推送显示屏更新消息到 WebSocket
* 推送显示屏更新消息到 SSE
* @param organizationId 科室ID
* @param queueDate 队列日期
* @param tenantId 租户ID
@@ -731,11 +734,11 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
message.put("data", displayData);
message.put("timestamp", System.currentTimeMillis());
// 推送到该科室的所有 WebSocket 连接
CallNumberWebSocket.pushToOrganization(organizationId, message);
// 推送到该科室的所有 SSE 连接
callNumberSseManager.pushToOrganization(organizationId, message);
} catch (Exception e) {
// WebSocket 推送失败不应该影响业务逻辑
// SSE 推送失败不应该影响业务逻辑
System.err.println("推送显示屏更新失败:" + e.getMessage());
}
}

View File

@@ -8,13 +8,18 @@ import com.openhis.web.triageandqueuemanage.dto.CallNumberDisplayResp;
import com.openhis.web.triageandqueuemanage.dto.TriageQueueActionReq;
import com.openhis.web.triageandqueuemanage.dto.TriageQueueAddReq;
import com.openhis.web.triageandqueuemanage.dto.TriageQueueAdjustReq;
import com.openhis.web.triageandqueuemanage.sse.CallNumberSseManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
@RestController
@Slf4j
@@ -23,6 +28,9 @@ public class TriageQueueController {
@Resource
private TriageQueueAppService triageQueueAppService;
@Resource
private CallNumberSseManager callNumberSseManager;
@GetMapping("/list")
public R<?> list(@RequestParam(value = "organizationId", required = false) Long organizationId,
@@ -97,6 +105,44 @@ public class TriageQueueController {
return R.fail("获取显示屏数据失败:" + e.getMessage());
}
}
/**
* 叫号显示屏SSE 实时推送
*/
@Anonymous
@GetMapping(value = "/display/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter streamDisplayData(
@RequestParam(required = false) String organizationId,
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date,
@RequestParam(required = false) Integer tenantId
) {
// 1) 解析科室与租户SSE 连接根据科室分组管理)
Long orgId = resolveOrganizationId(organizationId);
if (orgId == null) {
SseEmitter emitter = new SseEmitter(0L);
Map<String, Object> error = new HashMap<>();
error.put("type", "error");
error.put("message", "organizationId参数不合法或未获取到登录用户科室");
callNumberSseManager.sendToEmitter(emitter, error);
emitter.complete();
return emitter;
}
Integer actualTenantId = resolveTenantId(tenantId);
// 2) 创建并注册 SSE 连接
SseEmitter emitter = callNumberSseManager.addEmitter(orgId);
try {
// 3) 连接建立后,先推送一次初始化数据
CallNumberDisplayResp data = triageQueueAppService.getDisplayData(orgId, date, actualTenantId);
Map<String, Object> init = new HashMap<>();
init.put("type", "init");
init.put("data", data);
init.put("timestamp", System.currentTimeMillis());
callNumberSseManager.sendToEmitter(emitter, init);
} catch (Exception e) {
log.error("SSE初始化数据发送失败", e);
}
return emitter;
}
private Long resolveOrganizationId(String organizationId) {
if (!StringUtils.hasText(organizationId)) {