江体小程序和zlb接口开发 #1

Merged
XiangZ merged 32 commits from feat/script_v1 into master 2026-05-10 09:06:35 +00:00
10 changed files with 318 additions and 6 deletions
Showing only changes of commit f36766112f - Show all commits

View File

@@ -0,0 +1,17 @@
package com.xiang.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum ScheduleEnums {
DOMAIN_DYNAMIC_ANALYSIS_TASK(4, "domain", "domainDynamicAnalysisTask"),
;
private final Integer modeleCode;
private final String module;
private final String taskName;
}

View File

@@ -0,0 +1,144 @@
package com.xiang.common.factory.schedule;
import com.xiang.common.pojo.schedule.ScheduleOpeningConfigDO;
import com.xiang.common.pojo.schedule.TaskResult;
import com.xiang.common.pojo.schedule.ValidationResult;
import com.xiang.common.service.IScheduleOpeningConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
public abstract class BaseScheduleTaskTemplate {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private final IScheduleOpeningConfigService scheduleOpeningConfigService;
protected BaseScheduleTaskTemplate(IScheduleOpeningConfigService scheduleOpeningConfigService) {
this.scheduleOpeningConfigService = scheduleOpeningConfigService;
}
/**
* 模板方法 - 定义任务执行的标准流程
* 子类不应覆写此方法
*/
public final void run() {
String taskName = getTaskName();
Integer module = getModule();
LocalDateTime startTime = LocalDateTime.now();
logger.info("【{}】任务开始执行,开始时间:{}", taskName, startTime.format(formatter));
try {
// 1. 参数校验
logger.info("【{}】开始参数校验...", taskName);
ValidationResult validate = validate(module, taskName);
if (!validate.isValid()) {
logger.error("【{}】参数校验失败:{}", taskName, validate.getMessage());
onValidationFailure(validate);
return;
}
logger.info("【{}】参数校验通过", taskName);
// 2. 执行业务逻辑
logger.info("【{}】开始执行业务逻辑...", taskName);
TaskResult result = doExecute(validate.getValidatedParams());
// 3. 记录成功结果
recordSuccess(result, startTime);
} catch (Exception e) {
// 4. 记录失败结果
logger.error("【{}】任务执行异常", taskName, e);
recordFailure(e, startTime);
}
LocalDateTime endTime = LocalDateTime.now();
logger.info("【{}】任务结束,结束时间:{}", taskName, endTime.format(formatter));
}
/**
* 获取任务名称(子类必须实现)
*/
protected abstract String getTaskName();
/**
* 获取模块名称(子类必须实现)
* @return
*/
protected abstract Integer getModule();
/**
* 任务校验(子类必须实现)
* @return 校验结果,包含是否通过、错误信息、校验通过的参数对象
*/
private ValidationResult validate(Integer moduleCode, String taskName) {
ValidationResult validationResult = new ValidationResult();
boolean flag = checkTaskOpening(moduleCode, taskName);
validationResult.setValidatedParams(null);
validationResult.setValid(flag);
validationResult.setMessage(flag ? "" : "任务未开启");
return validationResult;
}
/**
* 校验任务是否开启
* @param moduleCode 模块id
* @param taskName 任务名称
* @return
*/
private boolean checkTaskOpening(Integer moduleCode, String taskName) {
ScheduleOpeningConfigDO configsByModule = scheduleOpeningConfigService.getConfigByModule(moduleCode, taskName);
if (Objects.isNull(configsByModule)) {
return false;
}
return Objects.equals(configsByModule.getStatus(), 1);
}
/**
* 具体的业务逻辑执行(子类必须实现)
* @param validatedParams 校验通过的参数
* @return 任务执行结果
*/
protected abstract TaskResult doExecute(Object validatedParams);
/**
* 记录成功结果 - 子类可选择性覆写
*/
protected void recordSuccess(TaskResult result, LocalDateTime startTime) {
LocalDateTime endTime = LocalDateTime.now();
long duration = java.time.Duration.between(startTime, endTime).toMillis();
logger.info("【{}】任务执行成功,耗时:{}ms结果概要{}",
getTaskName(), duration, result.getSummary());
// 可在此扩展:写入数据库、发送通知等
// 例如saveTaskLog(getTaskName(), "SUCCESS", duration, result.getDetail());
}
/**
* 记录失败结果 - 子类可选择性覆写
*/
protected void recordFailure(Exception e, LocalDateTime startTime) {
LocalDateTime endTime = LocalDateTime.now();
long duration = java.time.Duration.between(startTime, endTime).toMillis();
logger.error("【{}】任务执行失败,耗时:{}ms错误{}",
getTaskName(), duration, e.getMessage());
// 可在此扩展:写入数据库、发送告警等
// 例如saveTaskLog(getTaskName(), "FAILURE", duration, e.getMessage());
}
/**
* 参数校验失败时的处理 - 子类可选择性覆写
*/
protected void onValidationFailure(ValidationResult result) {
// 默认实现:仅记录日志
logger.warn("【{}】参数校验失败,跳过任务执行", getTaskName());
// 可在此扩展:发送通知、写入失败日志等
}
}

View File

@@ -0,0 +1,11 @@
package com.xiang.common.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xiang.common.pojo.schedule.ScheduleOpeningConfigDO;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface ScheduleOpeningConfigDao extends BaseMapper<ScheduleOpeningConfigDO> {
}

View File

@@ -0,0 +1,24 @@
package com.xiang.common.pojo.schedule;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("schedule_opening_config")
public class ScheduleOpeningConfigDO {
private Long id;
/**
* 模块id(0glados 1芬玩岛 2江体小程序 3江体zlb 4:ddns)
*/
private Integer module;
private String beanName;
private Integer status;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,17 @@
package com.xiang.common.pojo.schedule;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TaskResult {
/**
* 是否成功
*/
private boolean success;
private String summary;
private Object detail;
}

View File

@@ -0,0 +1,15 @@
package com.xiang.common.pojo.schedule;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.checkerframework.checker.units.qual.A;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ValidationResult {
private boolean valid;
private String message;
private Object validatedParams;
}

View File

@@ -0,0 +1,17 @@
package com.xiang.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiang.common.pojo.schedule.ScheduleOpeningConfigDO;
import java.util.List;
public interface IScheduleOpeningConfigService extends IService<ScheduleOpeningConfigDO> {
/**
* 根据模块id和任务名称查询
* @param moduleCode
* @param taskName
* @return
*/
ScheduleOpeningConfigDO getConfigByModule(Integer moduleCode, String taskName);
}

View File

@@ -0,0 +1,20 @@
package com.xiang.common.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiang.common.mapper.ScheduleOpeningConfigDao;
import com.xiang.common.pojo.schedule.ScheduleOpeningConfigDO;
import org.springframework.stereotype.Service;
@Service
public class ScheduleOpeningConfigServiceImpl extends ServiceImpl<ScheduleOpeningConfigDao, ScheduleOpeningConfigDO> implements IScheduleOpeningConfigService {
@Override
public ScheduleOpeningConfigDO getConfigByModule(Integer moduleCode, String taskName) {
LambdaQueryWrapper<ScheduleOpeningConfigDO> lqw = Wrappers.lambdaQuery();
lqw.eq(ScheduleOpeningConfigDO::getModule, moduleCode);
lqw.eq(ScheduleOpeningConfigDO::getBeanName, taskName);
return baseMapper.selectOne(lqw);
}
}

View File

@@ -1,20 +1,39 @@
package com.xiang.service.module.domain.schedule;
import com.xiang.common.enums.ScheduleEnums;
import com.xiang.common.factory.schedule.BaseScheduleTaskTemplate;
import com.xiang.common.pojo.schedule.TaskResult;
import com.xiang.common.service.IScheduleOpeningConfigService;
import com.xiang.common.utils.IpUtils;
import com.xiang.service.module.domain.service.IDomainService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Slf4j
@RequiredArgsConstructor
public class DomainDynamicAnalysisTask {
@Component
public class DomainDynamicAnalysisTask extends BaseScheduleTaskTemplate {
private final IDomainService IDomainService;
@Scheduled(cron = "0 0/30 * * * ? ")
public void dynamicDomainSchedule() {
public DomainDynamicAnalysisTask(IScheduleOpeningConfigService scheduleOpeningConfigService, IDomainService IDomainService) {
super(scheduleOpeningConfigService);
this.IDomainService = IDomainService;
}
@Override
protected Integer getModule() {
return ScheduleEnums.DOMAIN_DYNAMIC_ANALYSIS_TASK.getModeleCode();
}
@Override
protected String getTaskName() {
return ScheduleEnums.DOMAIN_DYNAMIC_ANALYSIS_TASK.getTaskName();
}
@Override
protected TaskResult doExecute(Object validatedParams) {
String publicIp = "";
TaskResult taskResult = new TaskResult();
try {
publicIp = IpUtils.getPublicIp();
} catch (Exception e) {
@@ -27,5 +46,10 @@ public class DomainDynamicAnalysisTask {
log.error("动态解析公网ip失败, ip:{}", publicIp, e);
}
}
taskResult.setSuccess(true);
taskResult.setSummary("");
taskResult.setDetail(null);
return taskResult;
}
}

View File

@@ -0,0 +1,23 @@
package com.xiang.service.module.domain.schedule;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@Component
@Slf4j
@RequiredArgsConstructor
@RestController
public class DomainDynamicAnalysisTaskConfig {
private final DomainDynamicAnalysisTask domainDynamicAnalysisTask;
@Scheduled(cron = "0 0/30 * * * ? ")
@GetMapping("/test")
public void dynamicDomainSchedule() {
domainDynamicAnalysisTask.run();
}
}