package com.vincent.rsf.openApi.service;
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
import com.vincent.rsf.openApi.tv.TvMonitorRedisKeys;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.stereotype.Service;
|
import org.springframework.util.StringUtils;
|
|
import javax.annotation.Resource;
|
import java.util.ArrayList;
|
import java.util.LinkedHashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* RCS 推送:写入与电视机后台相同的 Redis 格式(不修改 zy-monitor-admin / 电视机)
|
*/
|
@Slf4j
|
@Service
|
public class RcsTvCallbackService {
|
|
@Resource
|
@Qualifier("tvMonitorStringRedisTemplate")
|
private StringRedisTemplate tvMonitorStringRedisTemplate;
|
|
@Value("${tv-monitor.rcs-callback-token:}")
|
private String rcsCallbackToken;
|
|
public void assertToken(String headerToken) {
|
if (!StringUtils.hasText(rcsCallbackToken)) {
|
return;
|
}
|
if (!rcsCallbackToken.equals(headerToken)) {
|
throw new IllegalArgumentException("X-Rcs-Token 无效");
|
}
|
}
|
|
/**
|
* 解析输送线异常列表,写入 {@link TvMonitorRedisKeys#TV_MANUAL_ERROR_MSG}(分号拼接,与推送端 join 风格一致)
|
*/
|
public Map<String, Object> handleStationError(JsonNode body) {
|
if (body != null && body.isObject() && body.has("clear") && body.get("clear").asBoolean(false)) {
|
tvMonitorStringRedisTemplate.delete(TvMonitorRedisKeys.TV_MANUAL_ERROR_MSG);
|
return rcsOk(null);
|
}
|
JsonNode arr = resolveErrorArray(body);
|
if (arr == null || !arr.isArray() || arr.size() == 0) {
|
tvMonitorStringRedisTemplate.delete(TvMonitorRedisKeys.TV_MANUAL_ERROR_MSG);
|
return rcsOk(null);
|
}
|
List<String> parts = new ArrayList<>();
|
for (JsonNode item : arr) {
|
if (item == null || !item.isObject()) {
|
continue;
|
}
|
String staNo = text(item.get("staNo"));
|
String err = text(item.get("error"));
|
String plc = text(item.get("plcDesc"));
|
String msg = StringUtils.hasText(err) ? err : plc;
|
if (!StringUtils.hasText(msg)) {
|
continue;
|
}
|
if (StringUtils.hasText(staNo)) {
|
parts.add("[" + staNo + "]" + msg);
|
} else {
|
parts.add(msg);
|
}
|
}
|
if (parts.isEmpty()) {
|
tvMonitorStringRedisTemplate.delete(TvMonitorRedisKeys.TV_MANUAL_ERROR_MSG);
|
return rcsOk(null);
|
}
|
String value = String.join(";", parts);
|
tvMonitorStringRedisTemplate.opsForValue().set(TvMonitorRedisKeys.TV_MANUAL_ERROR_MSG, value);
|
log.info("RCS 报警已写入 Redis tvManualErrorMsg,条数={}", parts.size());
|
return rcsOk(value);
|
}
|
|
private static JsonNode resolveErrorArray(JsonNode body) {
|
if (body == null || body.isNull()) {
|
return null;
|
}
|
if (body.isArray()) {
|
return body;
|
}
|
if (body.isObject()) {
|
if (body.has("data") && body.get("data").isArray()) {
|
return body.get("data");
|
}
|
if (body.has("errors") && body.get("errors").isArray()) {
|
return body.get("errors");
|
}
|
}
|
return null;
|
}
|
|
private static String text(JsonNode n) {
|
if (n == null || n.isNull()) {
|
return "";
|
}
|
String s = n.asText("");
|
return s == null ? "" : s.trim();
|
}
|
|
/**
|
* 站点任务号写入 Redis Hash,供后续扩展;电视机 led 任务号仍来自 WCS 站点轮询
|
*/
|
public Map<String, Object> handleStationTaskNo(JsonNode body) {
|
if (body == null || body.isNull() || !body.isObject()) {
|
throw new IllegalArgumentException("body 须为 JSON 对象");
|
}
|
JsonNode dataNode = body.get("data");
|
JsonNode src = (dataNode != null && dataNode.isObject()) ? dataNode : body;
|
String staNo = text(body.get("staNo"));
|
if (!StringUtils.hasText(staNo)) {
|
staNo = text(src.get("staNo"));
|
}
|
String taskNo = text(src.get("taskNo"));
|
if (!StringUtils.hasText(staNo)) {
|
throw new IllegalArgumentException("staNo 不能为空");
|
}
|
if (!StringUtils.hasText(taskNo)) {
|
tvMonitorStringRedisTemplate.opsForHash().delete(TvMonitorRedisKeys.TV_RCS_STATION_TASK_NO, staNo);
|
} else {
|
tvMonitorStringRedisTemplate.opsForHash()
|
.put(TvMonitorRedisKeys.TV_RCS_STATION_TASK_NO, staNo, taskNo);
|
}
|
log.info("RCS 任务号已写入 Redis Hash staNo={} taskNo={}", staNo, taskNo);
|
Map<String, Object> payload = new LinkedHashMap<>();
|
payload.put("staNo", staNo);
|
payload.put("taskNo", taskNo);
|
return rcsOk(payload);
|
}
|
|
private Map<String, Object> rcsOk(Object data) {
|
Map<String, Object> m = new LinkedHashMap<>();
|
m.put("code", 200);
|
m.put("message", "请求成功");
|
m.put("timestamp", System.currentTimeMillis());
|
m.put("data", data);
|
return m;
|
}
|
}
|