|
@@ -65,10 +65,10 @@ public class MktMgmtRuleServiceImpl implements MktMgmtRuleService {
|
|
|
|
|
|
// 统一验证输入数据
|
|
|
if (ipList != null && !ipList.isEmpty()) {
|
|
|
- validateIpList(ipList);
|
|
|
+ IPUtils.validateIpList(ipList);
|
|
|
}
|
|
|
if (domainList != null && !domainList.isEmpty()) {
|
|
|
- validateDomainList(domainList);
|
|
|
+ DomainValidationUtil.validateDomainList(domainList);
|
|
|
}
|
|
|
if (keywords != null && !keywords.isEmpty()) {
|
|
|
validateKeywordList(keywords);
|
|
@@ -118,17 +118,25 @@ public class MktMgmtRuleServiceImpl implements MktMgmtRuleService {
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
- // 修改规则
|
|
|
- // 1. 更新主规则信息
|
|
|
- MktMgmtRule mktMgmtRule = mktMgmtRuleMapper.selectById(reqDto.getId());
|
|
|
- if (mktMgmtRule == null) {
|
|
|
- throw new BusinessException("规则不存在");
|
|
|
- }
|
|
|
+ Long ruleId = reqDto.getId();
|
|
|
MktMgmtRule rule = new MktMgmtRule();
|
|
|
BeanUtils.copyProperties(reqDto, rule);
|
|
|
- mktMgmtRuleMapper.updateById(rule);
|
|
|
-
|
|
|
- Long ruleId = reqDto.getId();
|
|
|
+ // 是否是全局配置
|
|
|
+ if (ruleId == 0L){
|
|
|
+ MktMgmtRule globalRule = mktMgmtRuleMapper.selectById(reqDto.getId());
|
|
|
+ if (globalRule == null) {
|
|
|
+ int insert = mktMgmtRuleMapper.insert(rule);
|
|
|
+ }else {
|
|
|
+ mktMgmtRuleMapper.updateById(rule);
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ // 1. 更新主规则信息
|
|
|
+ MktMgmtRule mktMgmtRule = mktMgmtRuleMapper.selectById(reqDto.getId());
|
|
|
+ if (mktMgmtRule == null) {
|
|
|
+ throw new BusinessException("规则不存在");
|
|
|
+ }
|
|
|
+ mktMgmtRuleMapper.updateById(rule);
|
|
|
+ }
|
|
|
|
|
|
// 2. 处理IP列表
|
|
|
updateIpList(ipList, ruleId);
|
|
@@ -393,15 +401,6 @@ public class MktMgmtRuleServiceImpl implements MktMgmtRuleService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 校验域名格式是否合法
|
|
|
- * @param domain 域名
|
|
|
- */
|
|
|
- private void validateDomain(String domain){
|
|
|
- if (!DomainValidationUtil.isValidDomain2(domain)) {
|
|
|
- throw new BusinessException("域名格式错误: " + domain);
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
/**
|
|
|
* 验证规则名是否重复
|
|
@@ -427,95 +426,6 @@ public class MktMgmtRuleServiceImpl implements MktMgmtRuleService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 验证IP列表,检查是否存在冲突
|
|
|
- * @param ipList IP列表
|
|
|
- */
|
|
|
- private void validateIpList(List<String> ipList) {
|
|
|
- if (ipList == null || ipList.isEmpty()) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // 过滤空值和去重
|
|
|
- List<String> validIps = ipList.stream()
|
|
|
- .filter(StringUtils::hasText)
|
|
|
- .map(String::trim)
|
|
|
- .toList();
|
|
|
-
|
|
|
- // 检查是否有重复的单IP
|
|
|
- Set<String> singleIps = new HashSet<>();
|
|
|
- Set<String> ipRanges = new HashSet<>();
|
|
|
-
|
|
|
- for (String ip : validIps) {
|
|
|
- if (ip.contains("/")) {
|
|
|
- // IP段格式
|
|
|
- ipRanges.add(ip);
|
|
|
- } else {
|
|
|
- // 单IP格式
|
|
|
- if (!singleIps.add(ip)) {
|
|
|
- throw new BusinessException("IP列表中存在重复的单IP: " + ip);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 检查是否有重复的IP段
|
|
|
- List<String> rangeList = validIps.stream()
|
|
|
- .filter(ip -> ip.contains("/"))
|
|
|
- .toList();
|
|
|
- Set<String> uniqueRanges = new HashSet<>(rangeList);
|
|
|
- if (rangeList.size() != uniqueRanges.size()) {
|
|
|
- throw new BusinessException("IP列表中存在重复的IP段");
|
|
|
- }
|
|
|
-
|
|
|
- // 检查单IP是否在IP段中
|
|
|
- for (String singleIp : singleIps) {
|
|
|
- for (String ipRange : ipRanges) {
|
|
|
- if (isIpInRange(singleIp, ipRange)) {
|
|
|
- throw new BusinessException("单IP '" + singleIp + "' 在IP段 '" + ipRange + "' 中,存在冲突");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 检查IP段之间是否重叠
|
|
|
- List<String> uniqueRangeList = new ArrayList<>(ipRanges);
|
|
|
- for (int i = 0; i < uniqueRangeList.size(); i++) {
|
|
|
- for (int j = i + 1; j < uniqueRangeList.size(); j++) {
|
|
|
- if (isIpRangesOverlap(uniqueRangeList.get(i), uniqueRangeList.get(j))) {
|
|
|
- throw new BusinessException("IP段 '" + uniqueRangeList.get(i) + "' 和 '" + uniqueRangeList.get(j) + "' 存在重叠");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 验证域名列表,检查格式和重复
|
|
|
- * @param domainList 域名列表
|
|
|
- */
|
|
|
- private void validateDomainList(List<String> domainList) {
|
|
|
- if (domainList == null || domainList.isEmpty()) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // 过滤空值,但不去重(保留重复项用于检测)
|
|
|
- List<String> validDomains = domainList.stream()
|
|
|
- .filter(StringUtils::hasText)
|
|
|
- .map(String::trim)
|
|
|
- .toList();
|
|
|
-
|
|
|
- // 检查是否有重复的域名
|
|
|
- Set<String> uniqueDomains = new HashSet<>();
|
|
|
- for (String domain : validDomains) {
|
|
|
- if (!uniqueDomains.add(domain)) {
|
|
|
- throw new BusinessException("域名列表中存在重复的域名: " + domain);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 校验每个域名的格式
|
|
|
- for (String domain : validDomains) {
|
|
|
- validateDomain(domain);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 验证关键字列表,检查重复
|
|
|
* @param keywordList 关键字列表
|
|
@@ -540,109 +450,6 @@ public class MktMgmtRuleServiceImpl implements MktMgmtRuleService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 检查单IP是否在IP段范围内
|
|
|
- * @param singleIp 单IP
|
|
|
- * @param ipRange IP段 (格式: 192.168.10.200/220 表示 192.168.10.200~192.168.10.220)
|
|
|
- * @return 是否在范围内
|
|
|
- */
|
|
|
- private boolean isIpInRange(String singleIp, String ipRange) {
|
|
|
- if (!IPUtils.isValidIp(singleIp)) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- String[] parts = ipRange.split("/");
|
|
|
- if (parts.length != 2) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- String startIp = parts[0];
|
|
|
- String endPart = parts[1];
|
|
|
-
|
|
|
- if (!IPUtils.isValidIp(startIp)) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- // 构造完整的结束IP
|
|
|
- String[] startParts = startIp.split("\\.");
|
|
|
- String endIp = String.format("%s.%s.%s.%s",
|
|
|
- startParts[0], startParts[1], startParts[2], endPart);
|
|
|
-
|
|
|
- if (!IPUtils.isValidIp(endIp)) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- long singleIpLong = ipToLong(singleIp);
|
|
|
- long startIpLong = ipToLong(startIp);
|
|
|
- long endIpLong = ipToLong(endIp);
|
|
|
-
|
|
|
- // 确保开始IP小于等于结束IP
|
|
|
- if (startIpLong > endIpLong) {
|
|
|
- long temp = startIpLong;
|
|
|
- startIpLong = endIpLong;
|
|
|
- endIpLong = temp;
|
|
|
- }
|
|
|
-
|
|
|
- return singleIpLong >= startIpLong && singleIpLong <= endIpLong;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 检查两个IP段是否重叠
|
|
|
- * @param range1 第一个IP段
|
|
|
- * @param range2 第二个IP段
|
|
|
- * @return 是否重叠
|
|
|
- */
|
|
|
- private boolean isIpRangesOverlap(String range1, String range2) {
|
|
|
- String[] parts1 = range1.split("/");
|
|
|
- String[] parts2 = range2.split("/");
|
|
|
-
|
|
|
- if (parts1.length != 2 || parts2.length != 2) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- String network1 = parts1[0];
|
|
|
- String network2 = parts2[0];
|
|
|
- int prefix1 = Integer.parseInt(parts1[1]);
|
|
|
- int prefix2 = Integer.parseInt(parts2[1]);
|
|
|
-
|
|
|
- if (!IPUtils.isValidIp(network1) || !IPUtils.isValidIp(network2)) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- long network1Long = ipToLong(network1);
|
|
|
- long network2Long = ipToLong(network2);
|
|
|
-
|
|
|
- // 计算网络掩码
|
|
|
- long mask1 = (0xFFFFFFFFL << (32 - prefix1)) & 0xFFFFFFFFL;
|
|
|
- long mask2 = (0xFFFFFFFFL << (32 - prefix2)) & 0xFFFFFFFFL;
|
|
|
-
|
|
|
- // 计算网络地址
|
|
|
- long net1 = network1Long & mask1;
|
|
|
- long net2 = network2Long & mask2;
|
|
|
-
|
|
|
- // 计算广播地址
|
|
|
- long broadcast1 = net1 | (~mask1 & 0xFFFFFFFFL);
|
|
|
- long broadcast2 = net2 | (~mask2 & 0xFFFFFFFFL);
|
|
|
-
|
|
|
- // 检查是否重叠:一个网络的开始地址小于等于另一个网络的结束地址,且一个网络的结束地址大于等于另一个网络的开始地址
|
|
|
- return net1 <= broadcast2 && broadcast1 >= net2;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 将IP地址转换为长整型
|
|
|
- * @param ip IP地址
|
|
|
- * @return 长整型值
|
|
|
- */
|
|
|
- private long ipToLong(String ip) {
|
|
|
- String[] parts = ip.split("\\.");
|
|
|
- long result = 0;
|
|
|
- for (int i = 0; i < 4; i++) {
|
|
|
- result |= Long.parseLong(parts[i]) << (24 - i * 8);
|
|
|
- }
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
/**
|
|
|
* 构建IP规则对象
|
|
|
* @param ip IP字符串
|