|
@@ -1,6 +1,7 @@
|
|
|
package com.pig4cloud.pig.marketing.service.impl;
|
|
|
|
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
@@ -10,9 +11,13 @@ import com.pig4cloud.pig.marketing.api.dto.rule.PageMktRuleDTO;
|
|
|
import com.pig4cloud.pig.marketing.api.dto.rule.SaveMktRuleDTO;
|
|
|
import com.pig4cloud.pig.marketing.api.entity.MktMgmtKeyword;
|
|
|
import com.pig4cloud.pig.marketing.api.entity.MktMgmtRule;
|
|
|
+import com.pig4cloud.pig.marketing.api.entity.MktMgmtRuleDomain;
|
|
|
+import com.pig4cloud.pig.marketing.api.entity.MktMgmtRuleIp;
|
|
|
import com.pig4cloud.pig.marketing.api.util.DomainValidationUtil;
|
|
|
import com.pig4cloud.pig.marketing.api.vo.rule.PageMktRuleVO;
|
|
|
import com.pig4cloud.pig.marketing.mapper.MktMgmtKeywordMapper;
|
|
|
+import com.pig4cloud.pig.marketing.mapper.MktMgmtRuleDomainMapper;
|
|
|
+import com.pig4cloud.pig.marketing.mapper.MktMgmtRuleIpMapper;
|
|
|
import com.pig4cloud.pig.marketing.mapper.MktMgmtRuleMapper;
|
|
|
import com.pig4cloud.pig.marketing.service.MktMgmtRuleService;
|
|
|
import lombok.AllArgsConstructor;
|
|
@@ -23,10 +28,7 @@ import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
import org.springframework.util.StringUtils;
|
|
|
|
|
|
-import java.util.Collections;
|
|
|
-import java.util.HashSet;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Set;
|
|
|
+import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
@@ -43,90 +45,95 @@ public class MktMgmtRuleServiceImpl implements MktMgmtRuleService {
|
|
|
|
|
|
private final MktMgmtKeywordMapper mktMgmtKeywordMapper;
|
|
|
|
|
|
+ private final MktMgmtRuleIpMapper mktMgmtRuleIpMapper;
|
|
|
+
|
|
|
+ private final MktMgmtRuleDomainMapper mktMgmtRuleDomainMapper;
|
|
|
+
|
|
|
/**
|
|
|
* 保存/修改营销规则
|
|
|
* @param reqDto 入参
|
|
|
*/
|
|
|
@Override
|
|
|
@Transactional
|
|
|
- public void saveMktRule(SaveMktRuleDTO reqDto) {
|
|
|
- // 处理IP格式解析
|
|
|
- String ip = reqDto.getIp();
|
|
|
- int ipMode = 0;
|
|
|
- String startIp = null;
|
|
|
- String endIp = null;
|
|
|
-
|
|
|
- // 处理IP格式
|
|
|
- if (StringUtils.hasText(ip)) {
|
|
|
- // 检查是否为IP段格式(包含"/")
|
|
|
- if (ip.contains("/")) {
|
|
|
- // IP段格式:192.168.1.1/10
|
|
|
- String[] parts = ip.split("/");
|
|
|
- if (parts.length == 2) {
|
|
|
- String startIpPart = parts[0];
|
|
|
- String endIpSuffix = parts[1];
|
|
|
- // 验证起始IP格式
|
|
|
- if (!IPUtils.isValidIp(startIpPart)) {
|
|
|
- throw new BusinessException("起始IP格式不正确");
|
|
|
- }
|
|
|
- // 计算结束IP
|
|
|
- try {
|
|
|
- // 解析起始IP
|
|
|
- String[] startParts = startIpPart.split("\\.");
|
|
|
- if (startParts.length == 4) {
|
|
|
+ public void saveMktRule(SaveMktRuleDTO reqDto){
|
|
|
+ // 验证IP列表
|
|
|
+ List<String> ipList = reqDto.getIp();
|
|
|
+ // 验证域名列表
|
|
|
+ List<String> domainList = reqDto.getDomain();
|
|
|
+
|
|
|
+ if (reqDto.getId() == null) {
|
|
|
+ // 新增规则
|
|
|
+ MktMgmtRule rule = new MktMgmtRule();
|
|
|
+ BeanUtils.copyProperties(reqDto, rule);
|
|
|
+ mktMgmtRuleMapper.insert(rule);
|
|
|
+
|
|
|
+ // 保存IP列表
|
|
|
+ if (ipList != null && !ipList.isEmpty()) {
|
|
|
+ for (String ip : ipList) {
|
|
|
+ if (StringUtils.hasText(ip)) {
|
|
|
+ MktMgmtRuleIp ruleIp = new MktMgmtRuleIp();
|
|
|
+ ruleIp.setRuleId(rule.getId());
|
|
|
+
|
|
|
+ // 处理IP格式
|
|
|
+ if (ip.contains("/")) {
|
|
|
+ // IP段格式
|
|
|
+ String[] parts = ip.split("/");
|
|
|
+ String startIp = parts[0];
|
|
|
+ String endIpSuffix = parts[1];
|
|
|
+
|
|
|
+ String[] startParts = startIp.split("\\.");
|
|
|
int endSuffix = Integer.parseInt(endIpSuffix);
|
|
|
- // 构建结束IP,保持前三段不变
|
|
|
- endIp = String.format("%s.%s.%s.%d",
|
|
|
+ String endIp = String.format("%s.%s.%s.%d",
|
|
|
startParts[0], startParts[1], startParts[2], endSuffix);
|
|
|
- startIp = startIpPart;
|
|
|
- ipMode = 2; // IP段模式
|
|
|
+
|
|
|
+ ruleIp.setIpMode(2); // IP段模式
|
|
|
+ ruleIp.setStartIp(startIp);
|
|
|
+ ruleIp.setEndIp(endIp);
|
|
|
+ } else {
|
|
|
+ // 单IP格式
|
|
|
+ ruleIp.setIpMode(1);
|
|
|
+ ruleIp.setStartIp(ip);
|
|
|
+ ruleIp.setEndIp("");
|
|
|
}
|
|
|
- } catch (NumberFormatException e) {
|
|
|
- throw new BusinessException("IP段格式不正确");
|
|
|
+ // 校验IP合法性
|
|
|
+ validateIp(ruleIp);
|
|
|
+ mktMgmtRuleIpMapper.insert(ruleIp);
|
|
|
}
|
|
|
- if (endIp == null) {
|
|
|
- throw new BusinessException("IP段格式不正确");
|
|
|
- }
|
|
|
- } else {
|
|
|
- throw new BusinessException("IP段格式不正确,应为:起始IP/结束IP后缀");
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 单IP格式
|
|
|
- if (!IPUtils.isValidIp(ip)) {
|
|
|
- throw new BusinessException("IP格式不正确");
|
|
|
}
|
|
|
- // 设置IP相关字段
|
|
|
- ipMode = 1;
|
|
|
- startIp = ip;
|
|
|
- }
|
|
|
- }
|
|
|
- // 验证域名
|
|
|
- if (StringUtils.hasText(reqDto.getDomain())){
|
|
|
- if (!DomainValidationUtil.isValidDomain(reqDto.getDomain())){
|
|
|
- throw new BusinessException("域名格式错误");
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- if (reqDto.getId() == null) {
|
|
|
- // 新增规则
|
|
|
- MktMgmtRule rule = new MktMgmtRule();
|
|
|
- BeanUtils.copyProperties(reqDto, rule);
|
|
|
- // 设置IP相关字段
|
|
|
- rule.setIpMode(ipMode);
|
|
|
- rule.setStartIp(startIp == null ? "" : startIp);
|
|
|
- rule.setEndIp(endIp == null ? "" : endIp);
|
|
|
- mktMgmtRuleMapper.insert(rule);
|
|
|
+ // 保存域名列表
|
|
|
+ if (domainList != null && !domainList.isEmpty()) {
|
|
|
+ for (String domain : domainList) {
|
|
|
+ if (StringUtils.hasText(domain)) {
|
|
|
+ // 校验域名
|
|
|
+ validateDomain(domain);
|
|
|
+ MktMgmtRuleDomain ruleDomain = new MktMgmtRuleDomain();
|
|
|
+ ruleDomain.setRuleId(rule.getId());
|
|
|
+ ruleDomain.setDomain(domain);
|
|
|
+ mktMgmtRuleDomainMapper.insert(ruleDomain);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
// 保存关键字
|
|
|
List<String> keywords = reqDto.getKeyword();
|
|
|
+ if (keywords != null && !keywords.isEmpty()) {
|
|
|
+ for (String keyword : keywords) {
|
|
|
+ if (StringUtils.hasText(keyword)) {
|
|
|
+ if (checkRuleKeywordExists(keyword)) {
|
|
|
+ throw new BusinessException("关键字 '" + keyword + "' 已存在,不能重复");
|
|
|
+ }
|
|
|
|
|
|
- for (String keyword : keywords) {
|
|
|
- MktMgmtKeyword mktMgmtKeyword = new MktMgmtKeyword();
|
|
|
- mktMgmtKeyword.setKeyword(keyword);
|
|
|
- mktMgmtKeyword.setRuleId(rule.getId());
|
|
|
- mktMgmtKeywordMapper.insert(mktMgmtKeyword);
|
|
|
+ MktMgmtKeyword mktMgmtKeyword = new MktMgmtKeyword();
|
|
|
+ mktMgmtKeyword.setKeyword(keyword);
|
|
|
+ mktMgmtKeyword.setRuleId(rule.getId());
|
|
|
+ mktMgmtKeywordMapper.insert(mktMgmtKeyword);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- }else {
|
|
|
+ }
|
|
|
+ else {
|
|
|
// 1. 更新主规则信息
|
|
|
MktMgmtRule mktMgmtRule = mktMgmtRuleMapper.selectById(reqDto.getId());
|
|
|
if (mktMgmtRule == null) {
|
|
@@ -134,14 +141,132 @@ public class MktMgmtRuleServiceImpl implements MktMgmtRuleService {
|
|
|
}
|
|
|
MktMgmtRule rule = new MktMgmtRule();
|
|
|
BeanUtils.copyProperties(reqDto, rule);
|
|
|
- // 设置IP相关字段
|
|
|
- rule.setIpMode(ipMode);
|
|
|
- rule.setStartIp(startIp == null ? "" : startIp);
|
|
|
- rule.setEndIp(endIp == null ? "" : endIp);
|
|
|
mktMgmtRuleMapper.updateById(rule);
|
|
|
|
|
|
- // 2. 处理关键字(先删除旧的,再添加新的)
|
|
|
+ // 2. 处理IP列表
|
|
|
Long ruleId = reqDto.getId();
|
|
|
+
|
|
|
+ // 查询现有的IP记录
|
|
|
+ List<MktMgmtRuleIp> oldIpRecords = mktMgmtRuleIpMapper.selectList(Wrappers.<MktMgmtRuleIp>lambdaQuery()
|
|
|
+ .eq(MktMgmtRuleIp::getRuleId, ruleId));
|
|
|
+
|
|
|
+ // 构建现有IP的映射(startIp -> record)
|
|
|
+ Map<String, MktMgmtRuleIp> oldIpMap = oldIpRecords.stream()
|
|
|
+ .collect(Collectors.toMap(MktMgmtRuleIp::getStartIp, ip -> ip));
|
|
|
+
|
|
|
+ // 构建新IP的映射
|
|
|
+ Map<String, MktMgmtRuleIp> newIpMap = new HashMap<>();
|
|
|
+ if (ipList != null && !ipList.isEmpty()) {
|
|
|
+ for (String ip : ipList) {
|
|
|
+ if (StringUtils.hasText(ip)) {
|
|
|
+ MktMgmtRuleIp ruleIp = new MktMgmtRuleIp();
|
|
|
+ ruleIp.setRuleId(ruleId);
|
|
|
+
|
|
|
+ // 处理IP格式
|
|
|
+ if (ip.contains("/")) {
|
|
|
+ // IP段格式
|
|
|
+ String[] parts = ip.split("/");
|
|
|
+ String startIpPart = parts[0];
|
|
|
+ String endIpSuffix = parts[1];
|
|
|
+
|
|
|
+ String[] startParts = startIpPart.split("\\.");
|
|
|
+ int endSuffix = Integer.parseInt(endIpSuffix);
|
|
|
+ String endIp = String.format("%s.%s.%s.%d",
|
|
|
+ startParts[0], startParts[1], startParts[2], endSuffix);
|
|
|
+
|
|
|
+ ruleIp.setIpMode(2); // IP段模式
|
|
|
+ ruleIp.setStartIp(startIpPart);
|
|
|
+ ruleIp.setEndIp(endIp);
|
|
|
+ } else {
|
|
|
+ // 单IP格式
|
|
|
+ ruleIp.setIpMode(1);
|
|
|
+ ruleIp.setStartIp(ip);
|
|
|
+ ruleIp.setEndIp("");
|
|
|
+ }
|
|
|
+
|
|
|
+ newIpMap.put(ruleIp.getStartIp(), ruleIp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理需要删除的IP(存在于旧列表但不存在于新列表)
|
|
|
+ List<Long> needDeleteIpIds = oldIpRecords.stream()
|
|
|
+ .filter(oldIp -> !newIpMap.containsKey(oldIp.getStartIp()))
|
|
|
+ .map(MktMgmtRuleIp::getId)
|
|
|
+ .toList();
|
|
|
+ if (!needDeleteIpIds.isEmpty()) {
|
|
|
+ mktMgmtRuleIpMapper.deleteByIds(needDeleteIpIds);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理需要新增的IP(存在于新列表但不存在于旧列表)
|
|
|
+ List<MktMgmtRuleIp> needAddIps = newIpMap.values().stream()
|
|
|
+ .filter(newIp -> !oldIpMap.containsKey(newIp.getStartIp()))
|
|
|
+ .toList();
|
|
|
+ if (!needAddIps.isEmpty()) {
|
|
|
+ for (MktMgmtRuleIp ruleIp : needAddIps) {
|
|
|
+ // 校验IP合法性
|
|
|
+ validateIp(ruleIp);
|
|
|
+ // 校验IP是否已存在
|
|
|
+ if (checkRuleIpExists(ruleIp, ruleId)) {
|
|
|
+ if (ruleIp.getIpMode() == 1) {
|
|
|
+ throw new BusinessException("IP '" + ruleIp.getStartIp() + "' 已存在或被其他IP段包含");
|
|
|
+ } else {
|
|
|
+ String[] end = ruleIp.getEndIp().split("\\.");
|
|
|
+ throw new BusinessException("IP段 '" + ruleIp.getStartIp() + "/" + end[3] + "' 已存在或与其他IP段重叠");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ mktMgmtRuleIpMapper.insert(ruleIp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 处理域名列表
|
|
|
+ // 查询现有的域名记录
|
|
|
+ List<MktMgmtRuleDomain> oldDomainRecords = mktMgmtRuleDomainMapper.selectList(Wrappers.<MktMgmtRuleDomain>lambdaQuery()
|
|
|
+ .eq(MktMgmtRuleDomain::getRuleId, ruleId));
|
|
|
+
|
|
|
+ // 构建现有域名的映射(domain -> record)
|
|
|
+ Map<String, MktMgmtRuleDomain> oldDomainMap = oldDomainRecords.stream()
|
|
|
+ .collect(Collectors.toMap(MktMgmtRuleDomain::getDomain, domain -> domain));
|
|
|
+
|
|
|
+ // 构建新域名的映射
|
|
|
+ Map<String, MktMgmtRuleDomain> newDomainMap = new HashMap<>();
|
|
|
+ if (domainList != null && !domainList.isEmpty()) {
|
|
|
+ for (String domain : domainList) {
|
|
|
+ if (StringUtils.hasText(domain)) {
|
|
|
+ MktMgmtRuleDomain ruleDomain = new MktMgmtRuleDomain();
|
|
|
+ ruleDomain.setRuleId(ruleId);
|
|
|
+ ruleDomain.setDomain(domain);
|
|
|
+ newDomainMap.put(domain, ruleDomain);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理需要删除的域名(存在于旧列表但不存在于新列表)
|
|
|
+ List<Long> needDeleteDomainIds = oldDomainRecords.stream()
|
|
|
+ .filter(oldDomain -> !newDomainMap.containsKey(oldDomain.getDomain()))
|
|
|
+ .map(MktMgmtRuleDomain::getId)
|
|
|
+ .toList();
|
|
|
+ if (!needDeleteDomainIds.isEmpty()) {
|
|
|
+ mktMgmtRuleDomainMapper.deleteByIds(needDeleteDomainIds);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理需要新增的域名(存在于新列表但不存在于旧列表)
|
|
|
+ List<MktMgmtRuleDomain> needAddDomains = newDomainMap.values().stream()
|
|
|
+ .filter(newDomain -> !oldDomainMap.containsKey(newDomain.getDomain()))
|
|
|
+ .toList();
|
|
|
+ if (!needAddDomains.isEmpty()) {
|
|
|
+ for (MktMgmtRuleDomain ruleDomain : needAddDomains) {
|
|
|
+ // 校验域名合法性
|
|
|
+ validateDomain(ruleDomain.getDomain());
|
|
|
+ // 校验新增的域名是否重复
|
|
|
+ if (checkRuleDomainExists(ruleDomain.getDomain(), ruleId)) {
|
|
|
+ throw new BusinessException("域名 '" + ruleDomain.getDomain() + "' 已存在,不能重复");
|
|
|
+ }
|
|
|
+ mktMgmtRuleDomainMapper.insert(ruleDomain);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 处理关键字(精确更新)
|
|
|
List<String> newKeywords = reqDto.getKeyword();
|
|
|
newKeywords = newKeywords == null ? Collections.emptyList() : newKeywords;
|
|
|
|
|
@@ -151,10 +276,10 @@ public class MktMgmtRuleServiceImpl implements MktMgmtRuleService {
|
|
|
.map(MktMgmtKeyword::getKeyword)
|
|
|
.collect(Collectors.toSet());
|
|
|
|
|
|
- // 2. 提取新关键字集合
|
|
|
+ // 提取新关键字集合
|
|
|
Set<String> newKeywordSet = new HashSet<>(newKeywords);
|
|
|
|
|
|
- // 3. 处理需要删除的关键字
|
|
|
+ // 处理需要删除的关键字(存在于旧列表但不存在于新列表)
|
|
|
List<Long> needDeleteIds = oldKeywords.stream()
|
|
|
.filter(keyword -> !newKeywordSet.contains(keyword.getKeyword()))
|
|
|
.map(MktMgmtKeyword::getId)
|
|
@@ -162,12 +287,18 @@ public class MktMgmtRuleServiceImpl implements MktMgmtRuleService {
|
|
|
if (!needDeleteIds.isEmpty()) {
|
|
|
mktMgmtKeywordMapper.deleteByIds(needDeleteIds);
|
|
|
}
|
|
|
- // 4. 处理需要新增的关键字(存在于新列表但不存在于旧列表)
|
|
|
+
|
|
|
+ // 处理需要新增的关键字(存在于新列表但不存在于旧列表)
|
|
|
List<String> needAddKeywords = newKeywordSet.stream()
|
|
|
.filter(keyword -> !oldKeywordSet.contains(keyword))
|
|
|
.toList();
|
|
|
if (!needAddKeywords.isEmpty()) {
|
|
|
for (String keyword : needAddKeywords) {
|
|
|
+ // 检查关键字是否重复
|
|
|
+ if (checkRuleKeywordExists(keyword)) {
|
|
|
+ throw new BusinessException("关键字 '" + keyword + "' 已被其他规则使用,不能重复");
|
|
|
+ }
|
|
|
+
|
|
|
MktMgmtKeyword mktMgmtKeyword = new MktMgmtKeyword();
|
|
|
mktMgmtKeyword.setKeyword(keyword);
|
|
|
mktMgmtKeyword.setRuleId(ruleId);
|
|
@@ -175,7 +306,6 @@ public class MktMgmtRuleServiceImpl implements MktMgmtRuleService {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -186,11 +316,14 @@ public class MktMgmtRuleServiceImpl implements MktMgmtRuleService {
|
|
|
@Override
|
|
|
@Transactional
|
|
|
public Boolean delMktRuleByIds(@ParameterObject List<Long> ids) {
|
|
|
- int i = mktMgmtRuleMapper.deleteByIds(ids);
|
|
|
- int delete = mktMgmtKeywordMapper.delete(Wrappers.<MktMgmtKeyword>lambdaQuery()
|
|
|
+ int delRule = mktMgmtRuleMapper.deleteByIds(ids);
|
|
|
+ int delKeyword = mktMgmtKeywordMapper.delete(Wrappers.<MktMgmtKeyword>lambdaQuery()
|
|
|
.in(MktMgmtKeyword::getRuleId, ids));
|
|
|
-
|
|
|
- return i > 0 && delete > 0;
|
|
|
+ int delIp = mktMgmtRuleIpMapper.delete(Wrappers.<MktMgmtRuleIp>lambdaQuery()
|
|
|
+ .in(MktMgmtRuleIp::getRuleId, ids));
|
|
|
+ int delDomain = mktMgmtRuleDomainMapper.delete(Wrappers.<MktMgmtRuleDomain>lambdaQuery()
|
|
|
+ .in(MktMgmtRuleDomain::getRuleId, ids));
|
|
|
+ return delRule > 0 && delKeyword > 0 && delIp > 0 && delDomain > 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -225,6 +358,154 @@ public class MktMgmtRuleServiceImpl implements MktMgmtRuleService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 1.2、IP匹配逻辑 - 从IP规则表中查询
|
|
|
+ if (StringUtils.hasText(reqDto.getIp())) {
|
|
|
+ String inputIp = reqDto.getIp();
|
|
|
+ // 验证输入IP格式
|
|
|
+ if (!IPUtils.isValidIp(inputIp)) {
|
|
|
+ throw new BusinessException("输入的IP格式不正确");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询匹配IP的规则ID列表
|
|
|
+ List<MktMgmtRuleIp> ipRules = mktMgmtRuleIpMapper.selectList(
|
|
|
+ Wrappers.<MktMgmtRuleIp>lambdaQuery()
|
|
|
+ .and(wrapper -> wrapper
|
|
|
+ // 匹配单IP模式:ipMode=1 且 startIp等于输入IP
|
|
|
+ .and(w -> w.eq(MktMgmtRuleIp::getIpMode, 1)
|
|
|
+ .eq(MktMgmtRuleIp::getStartIp, inputIp))
|
|
|
+ // 匹配IP段模式:ipMode=2 且 输入IP在startIp和endIp范围内
|
|
|
+ .or(w -> w.eq(MktMgmtRuleIp::getIpMode, 2)
|
|
|
+ .apply("INET_ATON({0}) BETWEEN INET_ATON(start_ip) AND INET_ATON(end_ip)", inputIp))
|
|
|
+ )
|
|
|
+ );
|
|
|
+
|
|
|
+ if (!ipRules.isEmpty()) {
|
|
|
+ List<Long> ruleIds = ipRules.stream()
|
|
|
+ .map(MktMgmtRuleIp::getRuleId)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ queryWrapper.in("id", ruleIds);
|
|
|
+ } else {
|
|
|
+ // 如果没有找到匹配的IP规则,返回空结果
|
|
|
+ return new Page<>();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1.3、域名模糊查询 - 从域名规则表中查询
|
|
|
+ if (StringUtils.hasText(reqDto.getDomain())) {
|
|
|
+ // 查询匹配域名的规则ID列表
|
|
|
+ List<MktMgmtRuleDomain> domainRules = mktMgmtRuleDomainMapper.selectList(
|
|
|
+ Wrappers.<MktMgmtRuleDomain>lambdaQuery()
|
|
|
+ .like(MktMgmtRuleDomain::getDomain, reqDto.getDomain())
|
|
|
+ );
|
|
|
+
|
|
|
+ if (!domainRules.isEmpty()) {
|
|
|
+ List<Long> ruleIds = domainRules.stream()
|
|
|
+ .map(MktMgmtRuleDomain::getRuleId)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ queryWrapper.in("id", ruleIds);
|
|
|
+ } else {
|
|
|
+ // 如果没有找到匹配的域名规则,返回空结果
|
|
|
+ return new Page<>();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 按创建时间倒序排列
|
|
|
+ queryWrapper.orderByDesc("create_time");
|
|
|
+
|
|
|
+ // 执行分页查询
|
|
|
+ Page<MktMgmtRule> rulePage = mktMgmtRuleMapper.selectPage(page, queryWrapper);
|
|
|
+
|
|
|
+ // 转换为VO对象
|
|
|
+ Page<PageMktRuleVO> resultPage = new Page<>(reqDto.getCurrent(), reqDto.getSize());
|
|
|
+ resultPage.setTotal(rulePage.getTotal());
|
|
|
+ resultPage.setPages(rulePage.getPages());
|
|
|
+
|
|
|
+ List<PageMktRuleVO> voList = rulePage.getRecords().stream().map(rule -> {
|
|
|
+ PageMktRuleVO vo = new PageMktRuleVO();
|
|
|
+ BeanUtils.copyProperties(rule, vo);
|
|
|
+
|
|
|
+ // 查询该规则对应的关键字列表
|
|
|
+ List<MktMgmtKeyword> keywords = mktMgmtKeywordMapper.selectList(
|
|
|
+ Wrappers.<MktMgmtKeyword>lambdaQuery()
|
|
|
+ .eq(MktMgmtKeyword::getRuleId, rule.getId())
|
|
|
+ );
|
|
|
+
|
|
|
+ List<String> keywordList = keywords.stream()
|
|
|
+ .map(MktMgmtKeyword::getKeyword)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ vo.setKeyword(keywordList);
|
|
|
+
|
|
|
+ // 查询该规则对应的IP列表
|
|
|
+ List<MktMgmtRuleIp> ipRules = mktMgmtRuleIpMapper.selectList(
|
|
|
+ Wrappers.<MktMgmtRuleIp>lambdaQuery()
|
|
|
+ .eq(MktMgmtRuleIp::getRuleId, rule.getId())
|
|
|
+ );
|
|
|
+
|
|
|
+ List<String> ipList = ipRules.stream().map(ipRule -> {
|
|
|
+ if (ipRule.getIpMode() == 1) {
|
|
|
+ // 单IP模式
|
|
|
+ return ipRule.getStartIp();
|
|
|
+ } else {
|
|
|
+ // IP段模式:从endIP中提取最后一段作为后缀
|
|
|
+ String startIp = ipRule.getStartIp();
|
|
|
+ String endIp = ipRule.getEndIp();
|
|
|
+
|
|
|
+ // 提取endIP的最后一段
|
|
|
+ String[] endParts = endIp.split("\\.");
|
|
|
+ String endSuffix = endParts[endParts.length - 1];
|
|
|
+
|
|
|
+ return startIp + "/" + endSuffix;
|
|
|
+ }
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ vo.setIp(ipList);
|
|
|
+
|
|
|
+ // 查询该规则对应的域名列表
|
|
|
+ List<MktMgmtRuleDomain> domainRules = mktMgmtRuleDomainMapper.selectList(
|
|
|
+ Wrappers.<MktMgmtRuleDomain>lambdaQuery()
|
|
|
+ .eq(MktMgmtRuleDomain::getRuleId, rule.getId())
|
|
|
+ );
|
|
|
+
|
|
|
+ List<String> domainList = domainRules.stream()
|
|
|
+ .map(MktMgmtRuleDomain::getDomain)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ vo.setDomain(domainList);
|
|
|
+
|
|
|
+ return vo;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+
|
|
|
+ resultPage.setRecords(voList);
|
|
|
+
|
|
|
+ return resultPage;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Page<PageMktRuleVO> pageMktRule2(PageMktRuleDTO reqDto) {
|
|
|
+ Page<MktMgmtRule> page = new Page<>(reqDto.getCurrent(), reqDto.getSize());
|
|
|
+
|
|
|
+ // 构建查询条件
|
|
|
+ QueryWrapper<MktMgmtRule> queryWrapper = new QueryWrapper<>();
|
|
|
+
|
|
|
+ // 1.1、关键字模糊查询 - 通过关联查询关键字表
|
|
|
+ if (StringUtils.hasText(reqDto.getKeyword())) {
|
|
|
+ // 先查询包含该关键字的规则ID
|
|
|
+ List<MktMgmtKeyword> keywords = mktMgmtKeywordMapper.selectList(
|
|
|
+ Wrappers.<MktMgmtKeyword>lambdaQuery()
|
|
|
+ .like(MktMgmtKeyword::getKeyword, reqDto.getKeyword())
|
|
|
+ );
|
|
|
+
|
|
|
+ if (!keywords.isEmpty()) {
|
|
|
+ List<Long> ruleIds = keywords.stream()
|
|
|
+ .map(MktMgmtKeyword::getRuleId)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ queryWrapper.in("id", ruleIds);
|
|
|
+ } else {
|
|
|
+ // 如果没有找到匹配的关键字,返回空结果
|
|
|
+ return new Page<>();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// 1.2、IP匹配逻辑 - 支持单IP和IP段匹配
|
|
|
if (StringUtils.hasText(reqDto.getIp())) {
|
|
|
String inputIp = reqDto.getIp();
|
|
@@ -294,6 +575,61 @@ public class MktMgmtRuleServiceImpl implements MktMgmtRuleService {
|
|
|
}
|
|
|
PageMktRuleVO result = new PageMktRuleVO();
|
|
|
BeanUtils.copyProperties(mktMgmtRule, result);
|
|
|
+
|
|
|
+ // 查询该规则对应的关键字列表
|
|
|
+ List<MktMgmtKeyword> keywords = mktMgmtKeywordMapper.selectList(
|
|
|
+ Wrappers.<MktMgmtKeyword>lambdaQuery()
|
|
|
+ .eq(MktMgmtKeyword::getRuleId, id)
|
|
|
+ );
|
|
|
+ List<String> keywordList = keywords.stream()
|
|
|
+ .map(MktMgmtKeyword::getKeyword)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ result.setKeyword(keywordList);
|
|
|
+
|
|
|
+ // 查询该规则对应的IP列表
|
|
|
+ List<MktMgmtRuleIp> ipRules = mktMgmtRuleIpMapper.selectList(
|
|
|
+ Wrappers.<MktMgmtRuleIp>lambdaQuery()
|
|
|
+ .eq(MktMgmtRuleIp::getRuleId, id)
|
|
|
+ );
|
|
|
+
|
|
|
+ List<String> ipList = ipRules.stream().map(ipRule -> {
|
|
|
+ if (ipRule.getIpMode() == 1) {
|
|
|
+ // 单IP模式
|
|
|
+ return ipRule.getStartIp();
|
|
|
+ } else {
|
|
|
+ // IP段模式:从endIP中提取最后一段作为后缀
|
|
|
+ String startIp = ipRule.getStartIp();
|
|
|
+ String endIp = ipRule.getEndIp();
|
|
|
+
|
|
|
+ // 提取endIP的最后一段
|
|
|
+ String[] endParts = endIp.split("\\.");
|
|
|
+ String endSuffix = endParts[endParts.length - 1];
|
|
|
+
|
|
|
+ return startIp + "/" + endSuffix;
|
|
|
+ }
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ result.setIp(ipList);
|
|
|
+
|
|
|
+ // 查询该规则对应的域名列表
|
|
|
+ List<MktMgmtRuleDomain> domainRules = mktMgmtRuleDomainMapper.selectList(
|
|
|
+ Wrappers.<MktMgmtRuleDomain>lambdaQuery()
|
|
|
+ .eq(MktMgmtRuleDomain::getRuleId, id)
|
|
|
+ );
|
|
|
+
|
|
|
+ List<String> domainList = domainRules.stream()
|
|
|
+ .map(MktMgmtRuleDomain::getDomain)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ result.setDomain(domainList);
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ public PageMktRuleVO getMktRuleById2(Long id) {
|
|
|
+ MktMgmtRule mktMgmtRule = mktMgmtRuleMapper.selectById(id);
|
|
|
+ if (mktMgmtRule == null){
|
|
|
+ throw new BusinessException("规则不存在");
|
|
|
+ }
|
|
|
+ PageMktRuleVO result = new PageMktRuleVO();
|
|
|
+ BeanUtils.copyProperties(mktMgmtRule, result);
|
|
|
// 查询该规则对应关键字列表
|
|
|
List<MktMgmtKeyword> keywords = mktMgmtKeywordMapper.selectList(Wrappers.<MktMgmtKeyword>lambdaQuery()
|
|
|
.eq(MktMgmtKeyword::getRuleId, id));
|
|
@@ -303,4 +639,105 @@ public class MktMgmtRuleServiceImpl implements MktMgmtRuleService {
|
|
|
result.setKeyword(keywordList);
|
|
|
return result;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 校验IP格式是否合法
|
|
|
+ * @param ruleIp IP信息
|
|
|
+ */
|
|
|
+ private void validateIp(MktMgmtRuleIp ruleIp){
|
|
|
+ if (!IPUtils.isValidIp(ruleIp.getStartIp())){
|
|
|
+ throw new BusinessException("start ip 格式不合法(IPv4)");
|
|
|
+ }
|
|
|
+ if (ruleIp.getIpMode() == 2){
|
|
|
+ if (!IPUtils.isValidIp(ruleIp.getEndIp())){
|
|
|
+ throw new BusinessException("end ip 格式不合法(IPv4)");
|
|
|
+ }
|
|
|
+ if (!IPUtils.isEndIpGreater(ruleIp.getStartIp(), ruleIp.getEndIp())){
|
|
|
+ throw new BusinessException("结束IP不能小于开始IP");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 校验域名格式是否合法
|
|
|
+ * @param domain 域名
|
|
|
+ */
|
|
|
+ private void validateDomain(String domain){
|
|
|
+ if (!DomainValidationUtil.isValidDomain(domain)) {
|
|
|
+ throw new BusinessException("域名格式错误: " + domain);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查规则IP是否重复
|
|
|
+ * @param ruleIp 要检查的IP信息
|
|
|
+ * @param ruleId 规则ID(更新时使用,新增时为null)
|
|
|
+ * @return 是否存在重复
|
|
|
+ */
|
|
|
+ private Boolean checkRuleIpExists(MktMgmtRuleIp ruleIp, Long ruleId){
|
|
|
+ QueryWrapper<MktMgmtRuleIp> query = new QueryWrapper<MktMgmtRuleIp>().eq("rule_id", ruleId);
|
|
|
+
|
|
|
+ query.and(wrapper -> {
|
|
|
+ // 单IP模式检查
|
|
|
+ if (ruleIp.getIpMode() == 1) {
|
|
|
+ String targetIp = ruleIp.getStartIp();
|
|
|
+ // 检查是否有相同单IP
|
|
|
+ wrapper.and(w -> w
|
|
|
+ .eq("ip_mode", 1)
|
|
|
+ .eq("start_ip", targetIp));
|
|
|
+
|
|
|
+ // 检查是否被IP段包含
|
|
|
+ wrapper.or(w -> w
|
|
|
+ .eq("ip_mode", 2)
|
|
|
+ .apply("INET_ATON({0}) BETWEEN INET_ATON(start_ip) AND INET_ATON(end_ip)", targetIp));
|
|
|
+ }
|
|
|
+
|
|
|
+ // IP段模式检查
|
|
|
+ if (ruleIp.getIpMode() == 2) {
|
|
|
+ String startIp = ruleIp.getStartIp();
|
|
|
+ String endIp = ruleIp.getEndIp();
|
|
|
+
|
|
|
+ // 检查是否与单IP重叠:单IP在输入IP段范围内
|
|
|
+ wrapper.and(w -> w
|
|
|
+ .eq("ip_mode", 1)
|
|
|
+ .apply("INET_ATON(start_ip) BETWEEN INET_ATON({0}) AND INET_ATON({1})", startIp, endIp));
|
|
|
+
|
|
|
+ // 检查是否与IP段重叠:两个IP段有交集
|
|
|
+ wrapper.or(w -> w
|
|
|
+ .eq("ip_mode", 2)
|
|
|
+ .and(w2 -> w2
|
|
|
+ .apply("INET_ATON(start_ip) BETWEEN INET_ATON({0}) AND INET_ATON({1})", startIp, endIp)
|
|
|
+ .or().apply("INET_ATON(end_ip) BETWEEN INET_ATON({0}) AND INET_ATON({1})", startIp, endIp)
|
|
|
+ .or().apply("INET_ATON({0}) BETWEEN INET_ATON(start_ip) AND INET_ATON(end_ip)", startIp)
|
|
|
+ )
|
|
|
+ );
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ return mktMgmtRuleIpMapper.selectCount(query) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查规则域名是否存在重复
|
|
|
+ * @param domain 要检查的域名
|
|
|
+ * @param ruleId 规则ID(更新时使用,新增时为null)
|
|
|
+ * @return 是否存在重复
|
|
|
+ */
|
|
|
+ private Boolean checkRuleDomainExists(String domain, Long ruleId) {
|
|
|
+ LambdaQueryWrapper<MktMgmtRuleDomain> wrapper = Wrappers.<MktMgmtRuleDomain>lambdaQuery()
|
|
|
+ .eq(MktMgmtRuleDomain::getDomain, domain)
|
|
|
+ .ne(MktMgmtRuleDomain::getRuleId, ruleId);
|
|
|
+ return mktMgmtRuleDomainMapper.selectCount(wrapper) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查规则关键则是否存在重复
|
|
|
+ * @param keyword 要检查的域名
|
|
|
+ * @return 是否存在重复
|
|
|
+ */
|
|
|
+ private Boolean checkRuleKeywordExists(String keyword){
|
|
|
+ LambdaQueryWrapper<MktMgmtKeyword> wrapper = Wrappers.<MktMgmtKeyword>lambdaQuery()
|
|
|
+ .eq(MktMgmtKeyword::getKeyword, keyword);
|
|
|
+ return mktMgmtKeywordMapper.selectCount(wrapper) > 0;
|
|
|
+ }
|
|
|
}
|