|
@@ -1,11 +1,22 @@
|
|
package com.pig4cloud.pig.marketing.service.impl;
|
|
package com.pig4cloud.pig.marketing.service.impl;
|
|
|
|
|
|
-
|
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
|
+import com.pig4cloud.pig.marketing.api.dto.MktMgmtPushRecordQueryDTO;
|
|
|
|
+import com.pig4cloud.pig.marketing.api.dto.MktMgmtPushRecordSaveDTO;
|
|
|
|
+import com.pig4cloud.pig.marketing.api.entity.MktMgmtKeyword;
|
|
|
|
+import com.pig4cloud.pig.marketing.api.entity.MktMgmtPushRecord;
|
|
|
|
+import com.pig4cloud.pig.marketing.api.entity.MktMgmtRule;
|
|
|
|
+import com.pig4cloud.pig.marketing.mapper.MktMgmtKeywordMapper;
|
|
import com.pig4cloud.pig.marketing.mapper.MktMgmtPushRecordMapper;
|
|
import com.pig4cloud.pig.marketing.mapper.MktMgmtPushRecordMapper;
|
|
|
|
+import com.pig4cloud.pig.marketing.mapper.MktMgmtRuleMapper;
|
|
import com.pig4cloud.pig.marketing.service.MktMgmtPushRecordService;
|
|
import com.pig4cloud.pig.marketing.service.MktMgmtPushRecordService;
|
|
import lombok.AllArgsConstructor;
|
|
import lombok.AllArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
|
+
|
|
|
|
+import java.util.List;
|
|
|
|
|
|
/**
|
|
/**
|
|
* @author: lwh
|
|
* @author: lwh
|
|
@@ -18,4 +29,213 @@ import org.springframework.stereotype.Service;
|
|
public class MktMgmtPushRecordServiceImpl implements MktMgmtPushRecordService {
|
|
public class MktMgmtPushRecordServiceImpl implements MktMgmtPushRecordService {
|
|
|
|
|
|
private final MktMgmtPushRecordMapper mktMgmtPushRecordMapper;
|
|
private final MktMgmtPushRecordMapper mktMgmtPushRecordMapper;
|
|
|
|
+ private final MktMgmtKeywordMapper mktMgmtKeywordMapper;
|
|
|
|
+ private final MktMgmtRuleMapper mktMgmtRuleMapper;
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public Page<MktMgmtPushRecord> pageQuery(MktMgmtPushRecordQueryDTO queryDTO) {
|
|
|
|
+ log.info("分页查询营销推送记录,查询条件:{}", queryDTO);
|
|
|
|
+
|
|
|
|
+ // 构建查询条件
|
|
|
|
+ LambdaQueryWrapper<MktMgmtPushRecord> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
+
|
|
|
|
+ // 规则名称模糊查询
|
|
|
|
+ if (StringUtils.hasText(queryDTO.getRuleName())) {
|
|
|
|
+ queryWrapper.like(MktMgmtPushRecord::getRuleName, queryDTO.getRuleName());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 触发条件模糊查询
|
|
|
|
+ if (StringUtils.hasText(queryDTO.getTriggerCondition())) {
|
|
|
|
+ queryWrapper.like(MktMgmtPushRecord::getTriggerCondition, queryDTO.getTriggerCondition());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ queryWrapper.eq(MktMgmtPushRecord::getDelFlag, "0");
|
|
|
|
+
|
|
|
|
+ // 按创建时间倒序排列
|
|
|
|
+ queryWrapper.orderByDesc(MktMgmtPushRecord::getCreateTime);
|
|
|
|
+
|
|
|
|
+ // 执行分页查询
|
|
|
|
+ Page<MktMgmtPushRecord> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
|
|
|
|
+ Page<MktMgmtPushRecord> result = mktMgmtPushRecordMapper.selectPage(page, queryWrapper);
|
|
|
|
+
|
|
|
|
+ log.info("分页查询完成,总记录数:{},当前页记录数:{}", result.getTotal(), result.getRecords().size());
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public Boolean saveRecord(MktMgmtPushRecordSaveDTO saveDTO) {
|
|
|
|
+ log.info("新增营销推送记录,数据:{}", saveDTO);
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ // 1. 根据推送内容匹配关键字
|
|
|
|
+ List<MktMgmtKeyword> keywords = findMatchingKeywords(saveDTO.getPushContent());
|
|
|
|
+ if (keywords.isEmpty()) {
|
|
|
|
+ log.warn("推送内容未匹配到任何关键字:{}", saveDTO.getPushContent());
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 2. 遍历匹配的关键字,查找对应的规则
|
|
|
|
+ for (MktMgmtKeyword keyword : keywords) {
|
|
|
|
+ MktMgmtRule rule = mktMgmtRuleMapper.selectById(keyword.getRuleId());
|
|
|
|
+ if (rule == null || "1".equals(rule.getDelFlag())) {
|
|
|
|
+ log.warn("关键字对应的规则不存在或已删除,ruleId:{}", keyword.getRuleId());
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 3. 验证IP地址
|
|
|
|
+ if (!validateIPAddress(rule, saveDTO.getPushIP())) {
|
|
|
|
+ log.warn("IP地址验证失败,规则:{},推送IP:{}", rule.getRuleName(), saveDTO.getPushIP());
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 4. 验证域名
|
|
|
|
+ if (!validateDomain(rule, saveDTO.getPushDomain())) {
|
|
|
|
+ log.warn("域名验证失败,规则:{},推送域名:{}", rule.getRuleName(), saveDTO.getPushDomain());
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 5. 构建触发条件描述
|
|
|
|
+ String triggerCondition = buildTriggerCondition(keyword.getKeyword(), rule, saveDTO.getPushIP(), saveDTO.getPushDomain());
|
|
|
|
+
|
|
|
|
+ // 6. 构建推送详情
|
|
|
|
+ String pushDetail = buildPushDetail(triggerCondition, saveDTO.getPushContent());
|
|
|
|
+
|
|
|
|
+ // 7. 创建推送记录
|
|
|
|
+ MktMgmtPushRecord record = new MktMgmtPushRecord();
|
|
|
|
+ record.setRuleName(rule.getRuleName());
|
|
|
|
+ record.setPushFrequency(rule.getPushFrequency());
|
|
|
|
+ record.setPushStatus(true); // 总为1-成功
|
|
|
|
+ record.setTriggerCondition(triggerCondition);
|
|
|
|
+ record.setPushDetail(pushDetail);
|
|
|
|
+ record.setDelFlag("0"); // 未删除
|
|
|
|
+
|
|
|
|
+ // 8. 保存到数据库
|
|
|
|
+ int result = mktMgmtPushRecordMapper.insert(record);
|
|
|
|
+ if (result > 0) {
|
|
|
|
+ log.info("营销推送记录新增成功,ID:{},规则:{}", record.getId(), rule.getRuleName());
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ log.warn("未找到匹配的规则或保存失败");
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("新增营销推送记录异常", e);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 根据推送内容查找匹配的关键字
|
|
|
|
+ */
|
|
|
|
+ private List<MktMgmtKeyword> findMatchingKeywords(String pushContent) {
|
|
|
|
+ if (!StringUtils.hasText(pushContent)) {
|
|
|
|
+ return List.of();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 查询所有未删除的关键字
|
|
|
|
+ LambdaQueryWrapper<MktMgmtKeyword> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
+ queryWrapper.eq(MktMgmtKeyword::getDelFlag, "0");
|
|
|
|
+ List<MktMgmtKeyword> allKeywords = mktMgmtKeywordMapper.selectList(queryWrapper);
|
|
|
|
+
|
|
|
|
+ // 过滤匹配的关键字
|
|
|
|
+ return allKeywords.stream()
|
|
|
|
+ .filter(keyword -> pushContent.contains(keyword.getKeyword()))
|
|
|
|
+ .toList();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 验证IP地址
|
|
|
|
+ */
|
|
|
|
+ private boolean validateIPAddress(MktMgmtRule rule, String pushIP) {
|
|
|
|
+ if (rule.getIpMode() == null || rule.getIpMode() == 0) {
|
|
|
|
+ // IP模式为0-空,不判断IP
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!StringUtils.hasText(pushIP)) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (rule.getIpMode() == 1) {
|
|
|
|
+ // IP模式为1-单IP,判断推送IP是否为start_ip
|
|
|
|
+ return pushIP.equals(rule.getStartIp());
|
|
|
|
+ } else if (rule.getIpMode() == 2) {
|
|
|
|
+ // IP模式为2-IP段,判断推送IP是否在start_ip和end_ip之间
|
|
|
|
+ if (!StringUtils.hasText(rule.getStartIp()) || !StringUtils.hasText(rule.getEndIp())) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ long pushIpLong = ipToLong(pushIP);
|
|
|
|
+ long startIpLong = ipToLong(rule.getStartIp());
|
|
|
|
+ long endIpLong = ipToLong(rule.getEndIp());
|
|
|
|
+
|
|
|
|
+ return pushIpLong >= startIpLong && pushIpLong <= endIpLong;
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("IP地址转换异常,pushIP:{},startIp:{},endIp:{}", pushIP, rule.getStartIp(), rule.getEndIp(), e);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 验证域名
|
|
|
|
+ */
|
|
|
|
+ private boolean validateDomain(MktMgmtRule rule, String pushDomain) {
|
|
|
|
+ // 如果规则中域名为空,则不判断域名
|
|
|
|
+ if (!StringUtils.hasText(rule.getDomain())) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 如果推送域名为空,则验证失败
|
|
|
|
+ if (!StringUtils.hasText(pushDomain)) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 判断推送域名是否为规则的域名
|
|
|
|
+ return rule.getDomain().equals(pushDomain);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 构建触发条件描述
|
|
|
|
+ */
|
|
|
|
+ private String buildTriggerCondition(String keyword, MktMgmtRule rule, String pushIP, String pushDomain) {
|
|
|
|
+ StringBuilder triggerCondition = new StringBuilder();
|
|
|
|
+ triggerCondition.append("关键字:").append(keyword);
|
|
|
|
+
|
|
|
|
+ // 添加IP信息
|
|
|
|
+ if (rule.getIpMode() != null && rule.getIpMode() > 0 && StringUtils.hasText(pushIP)) {
|
|
|
|
+ triggerCondition.append(",IP:").append(pushIP);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 添加域名信息
|
|
|
|
+ if (StringUtils.hasText(rule.getDomain()) && StringUtils.hasText(pushDomain)) {
|
|
|
|
+ triggerCondition.append(",域名:").append(pushDomain);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return triggerCondition.toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 构建推送详情
|
|
|
|
+ */
|
|
|
|
+ private String buildPushDetail(String triggerCondition, String pushContent) {
|
|
|
|
+ return "触发条件:" + triggerCondition + ",推送内容:" + pushContent;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * IP地址转Long(便于比较大小)
|
|
|
|
+ */
|
|
|
|
+ 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;
|
|
|
|
+ }
|
|
}
|
|
}
|