package com.vincent.rsf.openApi.tv; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.vincent.rsf.openApi.service.RcsTvCallbackService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; /** * 调用 RCS 站点接口,结果写入电视机 Redis,由 zy-monitor-admin WebSocket 推送到电视机 */ @Slf4j @Service public class TvRcsStationPollService { @Resource private RestTemplate restTemplate; @Resource private ObjectMapper objectMapper; @Resource private RcsTvCallbackService rcsTvCallbackService; @Resource private TvRcsStationPollProperties pollProperties; public void pollOnce() { if (StringUtils.hasText(pollProperties.getTaskNoPollUrl())) { try { String raw = restTemplate.getForObject(pollProperties.getTaskNoPollUrl(), String.class); applyTaskNoResponse(raw, pollProperties.getTaskNoStationId()); } catch (RestClientException e) { log.warn("RCS 任务号轮询 HTTP 失败: {}", e.getMessage()); } catch (Exception e) { log.warn("RCS 任务号轮询处理失败", e); } } if (StringUtils.hasText(pollProperties.getErrorPollUrl())) { try { String raw = restTemplate.getForObject(pollProperties.getErrorPollUrl(), String.class); applyErrorResponse(raw, pollProperties.getErrorStationId()); } catch (RestClientException e) { log.warn("RCS 异常轮询 HTTP 失败: {}", e.getMessage()); } catch (Exception e) { log.warn("RCS 异常轮询处理失败", e); } } } private void applyTaskNoResponse(String raw, String staNo) { if (!StringUtils.hasText(staNo)) { return; } if (!StringUtils.hasText(raw)) { rcsTvCallbackService.writeStationTaskNo(staNo, null); return; } String trimmed = raw.trim(); try { JsonNode root = objectMapper.readTree(trimmed); String taskNo = extractTaskNo(root); rcsTvCallbackService.writeStationTaskNo(staNo, taskNo); } catch (Exception e) { rcsTvCallbackService.writeStationTaskNo(staNo, trimmed); } } private static String extractTaskNo(JsonNode root) { if (root == null || root.isNull()) { return null; } if (root.isValueNode()) { return textNode(root); } String[] paths = {"taskNo", "task_no", "taskCode", "seqNum"}; for (String p : paths) { JsonNode n = root.get(p); if (n != null && !n.isNull() && StringUtils.hasText(textNode(n))) { return textNode(n); } } JsonNode data = root.get("data"); if (data != null && !data.isNull()) { if (data.isObject()) { for (String p : paths) { JsonNode n = data.get(p); if (n != null && !n.isNull() && StringUtils.hasText(textNode(n))) { return textNode(n); } } } else if (data.isValueNode()) { return textNode(data); } } JsonNode result = root.get("result"); if (result != null && result.isObject()) { for (String p : paths) { JsonNode n = result.get(p); if (n != null && !n.isNull() && StringUtils.hasText(textNode(n))) { return textNode(n); } } } return null; } private static String textNode(JsonNode n) { if (n == null || n.isNull()) { return ""; } String s = n.asText(""); return s == null ? "" : s.trim(); } private void applyErrorResponse(String raw, String defaultStaNo) throws Exception { JsonNode body = buildErrorCallbackBody(raw, defaultStaNo); rcsTvCallbackService.handleStationError(body); } /** * 归一成 {@link com.vincent.rsf.openApi.service.RcsTvCallbackService#handleStationError} 可识别的 data 数组 */ private JsonNode buildErrorCallbackBody(String raw, String defaultStaNo) throws Exception { if (!StringUtils.hasText(raw)) { return objectMapper.createArrayNode(); } String trimmed = raw.trim(); JsonNode root = objectMapper.readTree(trimmed); if (root.isArray()) { return fillStaNo((ArrayNode) root, defaultStaNo); } if (root.isObject()) { if (root.has("data") && root.get("data").isArray()) { ObjectNode o = objectMapper.createObjectNode(); o.set("data", fillStaNo((ArrayNode) root.get("data"), defaultStaNo)); return o; } if (root.has("errors") && root.get("errors").isArray()) { ObjectNode o = objectMapper.createObjectNode(); o.set("data", fillStaNo((ArrayNode) root.get("errors"), defaultStaNo)); return o; } String msg = firstMessageField(root); if (StringUtils.hasText(msg)) { return wrapSingleError(defaultStaNo, msg); } JsonNode data = root.get("data"); if (data != null && data.isTextual()) { return wrapSingleError(defaultStaNo, data.asText()); } } return wrapSingleError(defaultStaNo, trimmed); } private JsonNode wrapSingleError(String staNo, String msg) { ArrayNode arr = objectMapper.createArrayNode(); ObjectNode item = objectMapper.createObjectNode(); if (StringUtils.hasText(staNo)) { item.put("staNo", staNo); } item.put("error", msg); arr.add(item); ObjectNode body = objectMapper.createObjectNode(); body.set("data", arr); return body; } private static String firstMessageField(JsonNode o) { String[] keys = {"errorMsg", "message", "msg", "error", "plcDesc", "desc"}; for (String k : keys) { JsonNode n = o.get(k); if (n != null && !n.isNull() && StringUtils.hasText(n.asText("").trim())) { return n.asText("").trim(); } } return ""; } private ArrayNode fillStaNo(ArrayNode arr, String defaultStaNo) { for (int i = 0; i < arr.size(); i++) { JsonNode el = arr.get(i); if (!el.isObject()) { continue; } ObjectNode obj = (ObjectNode) el; if (!StringUtils.hasText(textNode(obj.get("staNo"))) && StringUtils.hasText(defaultStaNo)) { obj.put("staNo", defaultStaNo); } } return arr; } }