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