初始化v1.2

This commit is contained in:
gaoyutao
2025-11-24 16:19:09 +08:00
parent c0f51ef007
commit de49404116
918 changed files with 4236 additions and 4239 deletions
@@ -0,0 +1,41 @@
package com.tongran.mtragent.utils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
public class JsonDataParser {
private static final ObjectMapper objectMapper = new ObjectMapper();
/**
* 通用JSON解析方法(兼容对象和数组)
* @param jsonStr JSON字符串
* @param valueType 目标实体类类型
* @return 实体类List集合
*/
public static <T> List<T> parseJsonData(String jsonStr, Class<T> valueType) {
if (!StringUtils.hasText(jsonStr)) {
return new ArrayList<>();
}
try {
JsonNode rootNode = objectMapper.readTree(jsonStr);
if (rootNode.isArray()) {
// 处理数组格式JSON
return objectMapper.readValue(jsonStr,
objectMapper.getTypeFactory().constructCollectionType(List.class, valueType));
} else {
// 处理单个对象格式JSON
List<T> result = new ArrayList<>(1);
result.add(objectMapper.readValue(jsonStr, valueType));
return result;
}
} catch (Exception e) {
throw new RuntimeException("JSON解析失败: " + e.getMessage(), e);
}
}
}
@@ -0,0 +1,149 @@
package com.tongran.mtragent.utils;
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 org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
public class SwitchJsonDataParser {
private static final ObjectMapper objectMapper = new ObjectMapper();
/**
* 通用JSON解析方法(兼容对象和数组)
* @param jsonStr JSON字符串
* @param valueType 目标实体类类型
* @return 实体类List集合
*/
public static <T> List<T> parseJsonData(String jsonStr, Class<T> valueType) {
if (!StringUtils.hasText(jsonStr)) {
return new ArrayList<>();
}
try {
JsonNode rootNode = objectMapper.readTree(jsonStr);
if (rootNode.isArray()) {
// 处理数组格式JSON
if (isStringArrayContainingJsonObjects((ArrayNode) rootNode)) {
// 处理包含JSON对象字符串的数组 - 转换为真正的对象数组
ArrayNode processedArray = processStringJsonArrayToObjectArray((ArrayNode) rootNode);
return convertJsonArrayToList(processedArray, valueType);
} else {
// 处理普通JSON数组
processJsonArray((ArrayNode) rootNode);
return convertJsonArrayToList((ArrayNode) rootNode, valueType);
}
} else {
// 处理单个对象格式JSON
if (rootNode.isObject()) {
processJsonObject((ObjectNode) rootNode);
}
List<T> result = new ArrayList<>(1);
result.add(objectMapper.treeToValue(rootNode, valueType));
return result;
}
} catch (Exception e) {
throw new RuntimeException("JSON解析失败: " + e.getMessage(), e);
}
}
/**
* 将JsonArray转换为List<T>
*/
private static <T> List<T> convertJsonArrayToList(ArrayNode arrayNode, Class<T> valueType) throws Exception {
List<T> result = new ArrayList<>();
for (int i = 0; i < arrayNode.size(); i++) {
JsonNode element = arrayNode.get(i);
result.add(objectMapper.treeToValue(element, valueType));
}
return result;
}
/**
* 判断是否是包含JSON对象字符串的字符串数组
*/
private static boolean isStringArrayContainingJsonObjects(ArrayNode arrayNode) {
if (arrayNode.size() == 0) return false;
JsonNode firstElement = arrayNode.get(0);
if (firstElement.isTextual()) {
try {
String strValue = firstElement.textValue();
// 检查是否是JSON对象格式的字符串
if (strValue.startsWith("{") && strValue.endsWith("}")) {
objectMapper.readTree(strValue);
return true;
}
} catch (Exception e) {
return false;
}
}
return false;
}
/**
* 处理包含JSON对象字符串的字符串数组,转换为真正的对象数组
*/
private static ArrayNode processStringJsonArrayToObjectArray(ArrayNode arrayNode) {
ArrayNode resultArray = objectMapper.createArrayNode();
for (int i = 0; i < arrayNode.size(); i++) {
JsonNode element = arrayNode.get(i);
if (element.isTextual()) {
try {
String jsonString = element.textValue();
JsonNode jsonNode = objectMapper.readTree(jsonString);
if (jsonNode.isObject()) {
// 处理JSON对象中的 noSuchInstance
processJsonObject((ObjectNode) jsonNode);
resultArray.add(jsonNode);
} else {
resultArray.add(element);
}
} catch (Exception e) {
// 如果解析失败,保持原样
resultArray.add(element);
}
} else {
resultArray.add(element);
}
}
return resultArray;
}
/**
* 处理JSON数组
*/
private static void processJsonArray(ArrayNode arrayNode) {
for (int i = 0; i < arrayNode.size(); i++) {
JsonNode element = arrayNode.get(i);
if (element.isObject()) {
processJsonObject((ObjectNode) element);
} else if (element.isArray()) {
processJsonArray((ArrayNode) element);
}
}
}
/**
* 处理JSON对象
*/
private static void processJsonObject(ObjectNode objectNode) {
objectNode.fields().forEachRemaining(entry -> {
JsonNode value = entry.getValue();
if (value.isTextual() && "noSuchInstance".equals(value.textValue())) {
objectNode.putNull(entry.getKey());
} else if (value.isObject()) {
processJsonObject((ObjectNode) value);
} else if (value.isArray()) {
processJsonArray((ArrayNode) value);
}
});
}
}
@@ -0,0 +1,99 @@
package com.tongran.mtragent.utils;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.LinkedHashSet;
import java.util.Set;
public class TableRouterUtil {
// 日期格式
private static final DateTimeFormatter YEAR_MONTH_FORMAT =
DateTimeFormatter.ofPattern("yyyy_MM");
private static final DateTimeFormatter DATE_TIME_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 表名前缀
private static final String TABLE_PREFIX = "eps_initial_traffic";
// 表名前缀
private static final String TABLE_PREFIX_INITIAL = "initial_bandwidth_traffic";
/**
* 根据创建时间获取表名
* @param createTime 记录创建时间
* @return 对应的分表名称
* @throws IllegalArgumentException 如果createTime为null
*
* 示例:
* 2023-08-05 14:30:00 → eps_initial_traffic_2023_08_1_10
* 2023-08-15 09:15:00 → eps_initial_traffic_2023_08_11_20
* 2023-08-25 18:45:00 → eps_initial_traffic_2023_08_21_31
*/
public static String getTableName(LocalDateTime createTime) {
if (createTime == null) {
throw new IllegalArgumentException("创建时间不能为null");
}
String yearMonth = createTime.format(YEAR_MONTH_FORMAT);
int day = createTime.getDayOfMonth();
return String.format("%s_%s_%s",
TABLE_PREFIX_INITIAL,
yearMonth,
getDayRange(day));
}
/**
* 获取时间范围内涉及的所有表名
* @param startTime 开始时间 (格式: "yyyy-MM-dd HH:mm:ss")
* @param endTime 结束时间 (格式: "yyyy-MM-dd HH:mm:ss")
* @return 按时间顺序排列的表名集合
*/
public static Set<String> getTableNamesBetween(String startTime, String endTime) {
LocalDateTime start = parseDateTime(startTime);
LocalDateTime end = parseDateTime(endTime);
validateTimeRange(start, end);
Set<String> tableNames = new LinkedHashSet<>();
LocalDateTime current = start.withHour(0).withMinute(0).withSecond(0);
while (!current.isAfter(end)) {
tableNames.add(getTableName(current));
current = current.plusDays(1);
}
return tableNames;
}
// 解析字符串为LocalDateTime
private static LocalDateTime parseDateTime(String dateTimeStr) {
if (dateTimeStr == null || dateTimeStr.trim().isEmpty()) {
throw new IllegalArgumentException("时间字符串不能为空");
}
try {
return LocalDateTime.parse(dateTimeStr, DATE_TIME_FORMATTER);
} catch (Exception e) {
throw new IllegalArgumentException("时间格式必须为: yyyy-MM-dd HH:mm:ss", e);
}
}
// 获取日期区间
private static String getDayRange(int day) {
if (day < 1 || day > 31) {
throw new IllegalArgumentException("日期必须在1-31之间");
}
if (day <= 10) return "1_10";
if (day <= 20) return "11_20";
return "21_31";
}
// 验证时间范围
private static void validateTimeRange(LocalDateTime start, LocalDateTime end) {
if (start == null || end == null) {
throw new IllegalArgumentException("时间范围参数不能为null");
}
if (start.isAfter(end)) {
throw new IllegalArgumentException("开始时间不能晚于结束时间");
}
}
}
@@ -0,0 +1,285 @@
package com.tongran.mtragent.utils;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class WeChatWorkBot {
private static final ObjectMapper mapper = new ObjectMapper();
/**
* 发送基于模板的文本消息
* @param webhookUrl webhook地址
* @param template 消息模板,例如:"项目[项目名称]在[时间]发生[事件类型]"
* @param fieldValues 字段值的映射,key为中文字段名,value为实际值(支持String、Number、Boolean等)
* @return 是否发送成功
*/
public static boolean sendTemplateMessage(String webhookUrl, String template,
Map<String, Object> fieldValues) {
return sendTemplateMessage(webhookUrl, template, fieldValues, null, null, false);
}
/**
* 发送基于模板的文本消息(支持@功能)
* @param webhookUrl webhook地址
* @param template 消息模板
* @param fieldValues 字段值的映射
* @param mentionedMobiles 被@的用户列表(手机号)
* @param mentionedAll 是否@所有人
* @return 是否发送成功
*/
public static boolean sendTemplateMessage(String webhookUrl, String template,
Map<String, Object> fieldValues,
String[] mentionedMobiles, boolean mentionedAll) {
return sendTemplateMessage(webhookUrl, template, fieldValues, null, mentionedMobiles, mentionedAll);
}
/**
* 发送基于模板的文本消息(完整参数)
* @param webhookUrl webhook地址
* @param template 消息模板
* @param fieldValues 字段值的映射
* @param defaultValue 未找到字段时的默认值
* @param mentionedMobiles 被@的用户列表(手机号)
* @param mentionedAll 是否@所有人
* @return 是否发送成功
*/
public static boolean sendTemplateMessage(String webhookUrl, String template,
Map<String, Object> fieldValues, Object defaultValue,
String[] mentionedMobiles, boolean mentionedAll) {
try {
String actualContent = processTemplate(template, fieldValues, defaultValue);
return sendTextMessage(webhookUrl, actualContent, mentionedMobiles, mentionedAll);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 处理模板,替换字段占位符
* @param template 消息模板
* @param fieldValues 字段值映射
* @param defaultValue 默认值
* @return 处理后的消息内容
*/
public static String processTemplate(String template, Map<String, Object> fieldValues,
Object defaultValue) {
if (template == null) return "";
if (fieldValues == null || fieldValues.isEmpty()) {
return template;
}
Pattern pattern = Pattern.compile("\\[(.*?)\\]");
Matcher matcher = pattern.matcher(template);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
String fieldName = matcher.group(1);
Object fieldValueObj = fieldValues.get(fieldName);
String fieldValue = convertToString(fieldValueObj);
// 如果字段值为空,使用默认值或保留原占位符
if (fieldValue == null || fieldValue.trim().isEmpty()) {
fieldValue = convertToString(defaultValue);
if (fieldValue == null) {
fieldValue = "[" + fieldName + "]";
}
}
// 对替换值进行转义,防止正则表达式特殊字符问题
matcher.appendReplacement(result, Matcher.quoteReplacement(fieldValue));
}
matcher.appendTail(result);
return result.toString();
}
/**
* 将对象转换为字符串
* @param obj 要转换的对象
* @return 字符串表示
*/
private static String convertToString(Object obj) {
if (obj == null) {
return null;
}
if (obj instanceof String) {
return (String) obj;
} else if (obj instanceof Number || obj instanceof Boolean) {
return String.valueOf(obj);
} else if (obj instanceof java.util.Date) {
return new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((java.util.Date) obj);
} else {
return obj.toString();
}
}
/**
* 验证模板中的字段是否都有对应的值
* @param template 消息模板
* @param fieldValues 字段值映射
* @return 是否所有字段都有值
*/
public static boolean validateTemplate(String template, Map<String, Object> fieldValues) {
if (template == null || fieldValues == null) {
return false;
}
Pattern pattern = Pattern.compile("\\[(.*?)\\]");
Matcher matcher = pattern.matcher(template);
while (matcher.find()) {
String fieldName = matcher.group(1);
Object fieldValue = fieldValues.get(fieldName);
String strValue = convertToString(fieldValue);
if (!fieldValues.containsKey(fieldName) ||
strValue == null ||
strValue.trim().isEmpty()) {
return false;
}
}
return true;
}
/**
* 获取模板中的所有字段名
* @param template 消息模板
* @return 字段名列表
*/
public static java.util.List<String> getTemplateFields(String template) {
java.util.List<String> fields = new java.util.ArrayList<>();
if (template == null) {
return fields;
}
Pattern pattern = Pattern.compile("\\[(.*?)\\]");
Matcher matcher = pattern.matcher(template);
while (matcher.find()) {
fields.add(matcher.group(1));
}
return fields;
}
/**
* 发送Markdown模板消息
* @param webhookUrl webhook地址
* @param template Markdown模板
* @param fieldValues 字段值映射
* @return 是否发送成功
*/
public static boolean sendMarkdownTemplateMessage(String webhookUrl, String template,
Map<String, Object> fieldValues) {
return sendMarkdownTemplateMessage(webhookUrl, template, fieldValues, null);
}
/**
* 发送Markdown模板消息
* @param webhookUrl webhook地址
* @param template Markdown模板
* @param fieldValues 字段值映射
* @param defaultValue 默认值
* @return 是否发送成功
*/
public static boolean sendMarkdownTemplateMessage(String webhookUrl, String template,
Map<String, Object> fieldValues,
Object defaultValue) {
try {
String actualContent = processTemplate(template, fieldValues, defaultValue);
return sendMarkdownMessage(webhookUrl, actualContent);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 发送文本消息
*/
public static boolean sendTextMessage(String webhookUrl, String content) {
return sendTextMessage(webhookUrl, content, null, false);
}
/**
* 发送文本消息(支持@功能)
*/
public static boolean sendTextMessage(String webhookUrl, String content,
String[] mentionedMobiles, boolean mentionedAll) {
try {
Map<String, Object> message = new HashMap<>();
message.put("msgtype", "text");
Map<String, Object> textContent = new HashMap<>();
textContent.put("content", content);
if (mentionedAll) {
textContent.put("mentioned_mobile_list", new String[]{"@all"});
} else if (mentionedMobiles != null && mentionedMobiles.length > 0) {
textContent.put("mentioned_mobile_list", mentionedMobiles);
}
message.put("text", textContent);
return sendMessage(webhookUrl, mapper.writeValueAsString(message));
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 发送Markdown消息
*/
public static boolean sendMarkdownMessage(String webhookUrl, String content) {
try {
Map<String, Object> message = new HashMap<>();
message.put("msgtype", "markdown");
Map<String, Object> markdownContent = new HashMap<>();
markdownContent.put("content", content);
message.put("markdown", markdownContent);
return sendMessage(webhookUrl, mapper.writeValueAsString(message));
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private static boolean sendMessage(String webhookUrl, String jsonBody) {
try {
URL url = new URL(webhookUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setDoOutput(true);
connection.setConnectTimeout(5000);
connection.setReadTimeout(10000);
try (OutputStream os = connection.getOutputStream()) {
byte[] input = jsonBody.getBytes("UTF-8");
os.write(input, 0, input.length);
}
int responseCode = connection.getResponseCode();
return responseCode == 200;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}