新闻采集修改,完成发送邮件

This commit is contained in:
2025-11-18 17:56:10 +08:00
parent 049b6f2cf3
commit 9f3176194b
50 changed files with 3929 additions and 322 deletions

View File

@@ -5,21 +5,14 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.xyzh.api.crontab.CrontabService;
import org.xyzh.api.crontab.TaskMetaService;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.dto.crontab.TbCrontabTaskMeta;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.core.page.PageRequest;
import org.xyzh.common.dto.crontab.CreateTaskRequest;
import org.xyzh.common.dto.crontab.TbCrontabTask;
import org.xyzh.common.dto.crontab.TbCrontabLog;
import org.xyzh.crontab.pojo.CrontabItem;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.xyzh.common.utils.spring.SpringContextUtil;
import org.xyzh.crontab.config.CrontabProperties;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
@@ -38,157 +31,124 @@ public class CrontabController {
@Autowired
private CrontabService crontabService;
/**
* 获取可创建的定时任务
* @return
*/
@GetMapping("/getEnabledCrontabList")
public ResultDomain<CrontabItem> getEnabledCrontabList(@RequestParam(required = false) String param) {
ResultDomain<CrontabItem> rd = new ResultDomain<>();
try {
// 仅返回爬虫能力的元信息(任务模版列表),不包含调度相关内容
CrontabProperties props =
SpringContextUtil.getBean(CrontabProperties.class);
String jString = JSON.toJSONString(props);
props = JSON.parseObject(jString, CrontabProperties.class);
props.getItems().forEach(item->item.getMethods().forEach(
method->{
method.setClazz(null);
method.setExcuete_method(null);
}));
rd.success("ok", props.getItems());
} catch (Exception e) {
rd.fail("获取可创建定时任务失败: " + e.getMessage());
}
return rd;
}
@Autowired
private TaskMetaService taskMetaService;
/**
* 创建定时任务
* @param crontabItem
* @return
* 获取可创建定时任务(从数据库获取任务元数据列表)
* @return ResultDomain<TbCrontabTaskMeta>
*/
@PostMapping("/crontabTask")
public ResultDomain<TbCrontabTask> createCrontab(@RequestBody TbCrontabTask crontabItem) {
ResultDomain<TbCrontabTask> rd = new ResultDomain<>();
@GetMapping("/getEnabledCrontabList")
public ResultDomain<TbCrontabTaskMeta> getEnabledCrontabList(@RequestParam(required = false) String param) {
try {
// 根据前端传入的taskGroup和methodName都是中文显示名查找配置
if (crontabItem.getTaskGroup() == null || crontabItem.getTaskGroup().isEmpty()) {
rd.fail("任务分组不能为空");
return rd;
}
if (crontabItem.getMethodName() == null || crontabItem.getMethodName().isEmpty()) {
rd.fail("方法名称不能为空");
return rd;
}
// 根据taskGroup和methodName查找配置
CrontabItem.CrontabMethod method = findMethodByTaskGroupAndMethodName(
crontabItem.getTaskGroup(),
crontabItem.getMethodName()
);
if (method != null) {
// 填充beanName和实际的Java方法名
crontabItem.setBeanName(method.getClazz());
crontabItem.setMethodName(method.getExcuete_method());
// 将scriptPath添加到methodParams中
JSONObject methodParams = JSON.parseObject(crontabItem.getMethodParams());
methodParams.put("scriptPath", method.getPath());
crontabItem.setMethodParams(methodParams.toJSONString());
logger.info("创建任务 - taskGroup: {}, methodName: {}, beanName: {}, excuete_method: {}, scriptPath: {}",
crontabItem.getTaskGroup(), method.getName(), method.getClazz(),
method.getExcuete_method(), method.getPath());
} else {
rd.fail("未找到对应的配置: taskGroup=" + crontabItem.getTaskGroup()
+ ", methodName=" + crontabItem.getMethodName());
return rd;
}
return crontabService.createTask(crontabItem);
// 从数据库查询所有任务元数据
ResultDomain<TbCrontabTaskMeta> result = taskMetaService.getAllTaskMeta();
result.getDataList().forEach(item->{
item.setBeanName("");
item.setMethodName("");
item.setScriptPath("");
});
return result;
} catch (Exception e) {
logger.error("创建定时任务失败", e);
rd.fail("创建定时任务失败: " + e.getMessage());
ResultDomain<TbCrontabTaskMeta> rd = new ResultDomain<>();
rd.fail("获取可创建定时任务失败: " + e.getMessage());
return rd;
}
}
/**
* 根据taskGroup和methodName查找对应的方法配置
* 创建定时任务并绑定邮件接收人(从数据库获取元数据配置
* @param request 创建任务请求包含任务信息、元数据ID、是否使用默认接收人、额外接收人列表
* @return ResultDomain<TbCrontabTask>
*/
private CrontabItem.CrontabMethod findMethodByTaskGroupAndMethodName(String taskGroup, String methodName) {
CrontabProperties props = SpringContextUtil.getBean(CrontabProperties.class);
if (props == null || props.getItems() == null) {
return null;
}
for (CrontabItem item : props.getItems()) {
if (item.getName().equals(taskGroup)) {
for (CrontabItem.CrontabMethod method : item.getMethods()) {
if (method.getName().equals(methodName)) {
return method;
}
}
@PostMapping("/crontabTask")
public ResultDomain<TbCrontabTask> createCrontab(@RequestBody CreateTaskRequest request) {
ResultDomain<TbCrontabTask> rd = new ResultDomain<>();
try {
TbCrontabTask crontabItem = request.getTask();
String metaId = request.getMetaId();
// 验证元数据ID
if (metaId == null || metaId.isEmpty()) {
rd.fail("任务元数据ID不能为空");
return rd;
}
// 从数据库查询任务元数据
ResultDomain<TbCrontabTaskMeta> metaResult = taskMetaService.getTaskMetaById(metaId);
if (!metaResult.isSuccess() || metaResult.getData() == null) {
rd.fail("未找到对应的任务元数据: metaId=" + metaId);
return rd;
}
TbCrontabTaskMeta taskMeta = metaResult.getData();
// 填充任务信息
crontabItem.setTaskGroup(taskMeta.getCategory()); // 任务分组使用category
crontabItem.setBeanName(taskMeta.getBeanName());
crontabItem.setMethodName(taskMeta.getMethodName());
crontabItem.setMetaId(metaId); // 保存metaId执行时从数据库读取scriptPath
logger.info("创建任务并绑定接收人 - metaId: {}, name: {}, category: {}, defaultRecipient: {}, additionalCount: {}",
metaId, taskMeta.getName(), taskMeta.getCategory(),
crontabItem.getDefaultRecipient(),
request.getAdditionalRecipients() != null ? request.getAdditionalRecipients().size() : 0);
return crontabService.createTaskWithRecipients(request);
} catch (Exception e) {
logger.error("创建定时任务并绑定接收人失败", e);
rd.fail("创建定时任务并绑定接收人失败: " + e.getMessage());
return rd;
}
return null;
}
/**
* 更新定时任务
* @param crontabItem
* @return
* 更新定时任务并更新邮件接收人(从数据库获取元数据配置)
* @param request 更新任务请求包含任务信息、元数据ID、是否使用默认接收人、额外接收人列表
* @return ResultDomain<TbCrontabTask>
*/
@PutMapping("/crontabTask")
public ResultDomain<TbCrontabTask> updateCrontab(@RequestBody TbCrontabTask crontabItem) {
public ResultDomain<TbCrontabTask> updateCrontab(@RequestBody CreateTaskRequest request) {
ResultDomain<TbCrontabTask> rd = new ResultDomain<>();
try {
TbCrontabTask crontabItem = request.getTask();
String metaId = request.getMetaId();
// 确保id字段正确传递用于数据库更新
if (crontabItem.getTaskId() != null && crontabItem.getID() == null) {
crontabItem.setID(crontabItem.getTaskId());
}
// 根据前端传入的taskGroup和methodName都是中文显示名查找配置
if (crontabItem.getTaskGroup() == null || crontabItem.getTaskGroup().isEmpty()) {
rd.fail("任务分组不能为空");
return rd;
}
if (crontabItem.getMethodName() == null || crontabItem.getMethodName().isEmpty()) {
rd.fail("方法名称不能为空");
// 验证元数据ID
if (metaId == null || metaId.isEmpty()) {
rd.fail("任务元数据ID不能为空");
return rd;
}
// 根据taskGroup和methodName查找配置
CrontabItem.CrontabMethod method = findMethodByTaskGroupAndMethodName(
crontabItem.getTaskGroup(),
crontabItem.getMethodName()
);
if (method != null) {
// 填充beanName和实际的Java方法名
crontabItem.setBeanName(method.getClazz());
crontabItem.setMethodName(method.getExcuete_method());
// 将scriptPath添加到methodParams中
JSONObject methodParams = JSON.parseObject(crontabItem.getMethodParams());
methodParams.put("scriptPath", method.getPath());
crontabItem.setMethodParams(methodParams.toJSONString());
logger.info("更新任务 - id: {}, taskGroup: {}, methodName: {}, beanName: {}, excuete_method: {}, scriptPath: {}",
crontabItem.getID(), crontabItem.getTaskGroup(), method.getName(), method.getClazz(),
method.getExcuete_method(), method.getPath());
} else {
rd.fail("未找到对应的配置: taskGroup=" + crontabItem.getTaskGroup()
+ ", methodName=" + crontabItem.getMethodName());
// 从数据库查询任务元数据
ResultDomain<TbCrontabTaskMeta> metaResult = taskMetaService.getTaskMetaById(metaId);
if (!metaResult.isSuccess() || metaResult.getData() == null) {
rd.fail("未找到对应的任务元数据: metaId=" + metaId);
return rd;
}
return crontabService.updateTask(crontabItem);
TbCrontabTaskMeta taskMeta = metaResult.getData();
// 填充任务信息
crontabItem.setTaskGroup(taskMeta.getCategory());
crontabItem.setBeanName(taskMeta.getBeanName());
crontabItem.setMethodName(taskMeta.getMethodName());
crontabItem.setMetaId(metaId); // 保存metaId执行时从数据库读取scriptPath
logger.info("更新任务 - id: {}, metaId: {}, name: {}, category: {}, defaultRecipient: {}",
crontabItem.getID(), metaId, taskMeta.getName(), taskMeta.getCategory(),
crontabItem.getDefaultRecipient());
// 调用带接收人更新的方法
return crontabService.updateTaskWithRecipients(request);
} catch (Exception e) {
logger.error("更新定时任务失败", e);
rd.fail("更新定时任务失败: " + e.getMessage());
logger.error("更新定时任务并更新接收人失败", e);
rd.fail("更新定时任务并更新接收人失败: " + e.getMessage());
return rd;
}
}

View File

@@ -0,0 +1,76 @@
package org.xyzh.crontab.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.xyzh.api.crontab.EmailDefaultService;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.dto.crontab.TbCrontabEmailDefault;
/**
* @description 定时任务邮件通知默认接收人控制器
* @filename EmailDefaultController.java
* @author yslg
* @copyright xyzh
* @since 2025-11-18
*/
@RestController
@RequestMapping("/crontab/email/default")
public class EmailDefaultController {
private static final Logger logger = LoggerFactory.getLogger(EmailDefaultController.class);
@Autowired
private EmailDefaultService emailDefaultService;
/**
* @description 创建默认接收人
* @param emailDefault 默认接收人
* @return ResultDomain<TbCrontabEmailDefault>
*/
@PostMapping
public ResultDomain<TbCrontabEmailDefault> createDefault(@RequestBody TbCrontabEmailDefault emailDefault) {
return emailDefaultService.createDefault(emailDefault);
}
/**
* @description 更新默认接收人
* @param emailDefault 默认接收人
* @return ResultDomain<TbCrontabEmailDefault>
*/
@PutMapping
public ResultDomain<TbCrontabEmailDefault> updateDefault(@RequestBody TbCrontabEmailDefault emailDefault) {
return emailDefaultService.updateDefault(emailDefault);
}
/**
* @description 删除默认接收人
* @param defaultId 默认ID
* @return ResultDomain<Boolean>
*/
@DeleteMapping("/{defaultId}")
public ResultDomain<Boolean> deleteDefault(@PathVariable String defaultId) {
return emailDefaultService.deleteDefault(defaultId);
}
/**
* @description 根据defaultId查询
* @param defaultId 默认ID
* @return ResultDomain<TbCrontabEmailDefault>
*/
@GetMapping("/{defaultId}")
public ResultDomain<TbCrontabEmailDefault> getDefaultById(@PathVariable String defaultId) {
return emailDefaultService.getDefaultById(defaultId);
}
/**
* @description 根据metaId查询
* @param metaId 元数据ID
* @return ResultDomain<TbCrontabEmailDefault>
*/
@GetMapping("/meta/{metaId}")
public ResultDomain<TbCrontabEmailDefault> getDefaultByMetaId(@PathVariable String metaId) {
return emailDefaultService.getDefaultByMetaId(metaId);
}
}

View File

@@ -0,0 +1,109 @@
package org.xyzh.crontab.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.xyzh.api.crontab.EmailRecipientService;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.core.page.PageRequest;
import org.xyzh.common.dto.crontab.TbCrontabEmailRecipient;
import java.util.List;
/**
* @description 定时任务邮件接收人控制器
* @filename EmailRecipientController.java
* @author yslg
* @copyright xyzh
* @since 2025-11-18
*/
@RestController
@RequestMapping("/crontab/email/recipient")
public class EmailRecipientController {
private static final Logger logger = LoggerFactory.getLogger(EmailRecipientController.class);
@Autowired
private EmailRecipientService emailRecipientService;
/**
* @description 创建邮件接收人
* @param recipient 邮件接收人
* @return ResultDomain<TbCrontabEmailRecipient>
*/
@PostMapping
public ResultDomain<TbCrontabEmailRecipient> createRecipient(@RequestBody TbCrontabEmailRecipient recipient) {
return emailRecipientService.createRecipient(recipient);
}
/**
* @description 批量创建邮件接收人
* @param recipients 邮件接收人列表
* @return ResultDomain<Boolean>
*/
@PostMapping("/batch")
public ResultDomain<Boolean> batchCreateRecipient(@RequestBody List<TbCrontabEmailRecipient> recipients) {
return emailRecipientService.batchCreateRecipient(recipients);
}
/**
* @description 更新邮件接收人
* @param recipient 邮件接收人
* @return ResultDomain<TbCrontabEmailRecipient>
*/
@PutMapping
public ResultDomain<TbCrontabEmailRecipient> updateRecipient(@RequestBody TbCrontabEmailRecipient recipient) {
return emailRecipientService.updateRecipient(recipient);
}
/**
* @description 删除邮件接收人
* @param recipientId 接收人ID
* @return ResultDomain<Boolean>
*/
@DeleteMapping("/{recipientId}")
public ResultDomain<Boolean> deleteRecipient(@PathVariable String recipientId) {
return emailRecipientService.deleteRecipient(recipientId);
}
/**
* @description 根据ID查询
* @param recipientId 接收人ID
* @return ResultDomain<TbCrontabEmailRecipient>
*/
@GetMapping("/{recipientId}")
public ResultDomain<TbCrontabEmailRecipient> getRecipientById(@PathVariable String recipientId) {
return emailRecipientService.getRecipientById(recipientId);
}
/**
* @description 根据任务ID查询接收人列表
* @param taskId 任务ID
* @return ResultDomain<TbCrontabEmailRecipient>
*/
@GetMapping("/task/{taskId}")
public ResultDomain<TbCrontabEmailRecipient> getRecipientsByTaskId(@PathVariable String taskId) {
return emailRecipientService.getRecipientsByTaskId(taskId);
}
/**
* @description 分页查询邮件接收人
* @param pageRequest 分页请求
* @return ResultDomain<TbCrontabEmailRecipient>
*/
@PostMapping("/page")
public ResultDomain<TbCrontabEmailRecipient> getRecipientPage(@RequestBody PageRequest<TbCrontabEmailRecipient> pageRequest) {
return emailRecipientService.getRecipientPage(pageRequest);
}
/**
* @description 删除任务的所有接收人
* @param taskId 任务ID
* @return ResultDomain<Boolean>
*/
@DeleteMapping("/task/{taskId}")
public ResultDomain<Boolean> deleteRecipientsByTaskId(@PathVariable String taskId) {
return emailRecipientService.deleteRecipientsByTaskId(taskId);
}
}

View File

@@ -0,0 +1,96 @@
package org.xyzh.crontab.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.xyzh.api.crontab.TaskMetaService;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.core.page.PageRequest;
import org.xyzh.common.dto.crontab.TbCrontabTaskMeta;
/**
* @description 定时任务元数据控制器
* @filename TaskMetaController.java
* @author yslg
* @copyright xyzh
* @since 2025-11-18
*/
@RestController
@RequestMapping("/crontab/meta")
public class TaskMetaController {
private static final Logger logger = LoggerFactory.getLogger(TaskMetaController.class);
@Autowired
private TaskMetaService taskMetaService;
/**
* @description 创建任务元数据
* @param taskMeta 任务元数据
* @return ResultDomain<TbCrontabTaskMeta>
*/
@PostMapping
public ResultDomain<TbCrontabTaskMeta> createTaskMeta(@RequestBody TbCrontabTaskMeta taskMeta) {
return taskMetaService.createTaskMeta(taskMeta);
}
/**
* @description 更新任务元数据
* @param taskMeta 任务元数据
* @return ResultDomain<TbCrontabTaskMeta>
*/
@PutMapping
public ResultDomain<TbCrontabTaskMeta> updateTaskMeta(@RequestBody TbCrontabTaskMeta taskMeta) {
return taskMetaService.updateTaskMeta(taskMeta);
}
/**
* @description 删除任务元数据
* @param metaId 元数据ID
* @return ResultDomain<Boolean>
*/
@DeleteMapping("/{metaId}")
public ResultDomain<Boolean> deleteTaskMeta(@PathVariable String metaId) {
return taskMetaService.deleteTaskMeta(metaId);
}
/**
* @description 根据ID查询任务元数据
* @param metaId 元数据ID
* @return ResultDomain<TbCrontabTaskMeta>
*/
@GetMapping("/{metaId}")
public ResultDomain<TbCrontabTaskMeta> getTaskMetaById(@PathVariable String metaId) {
return taskMetaService.getTaskMetaById(metaId);
}
/**
* @description 查询所有任务元数据
* @return ResultDomain<TbCrontabTaskMeta>
*/
@GetMapping("/all")
public ResultDomain<TbCrontabTaskMeta> getAllTaskMeta() {
return taskMetaService.getAllTaskMeta();
}
/**
* @description 根据分类查询任务元数据
* @param category 分类
* @return ResultDomain<TbCrontabTaskMeta>
*/
@GetMapping("/category/{category}")
public ResultDomain<TbCrontabTaskMeta> getTaskMetaByCategory(@PathVariable String category) {
return taskMetaService.getTaskMetaByCategory(category);
}
/**
* @description 分页查询任务元数据
* @param pageRequest 分页请求
* @return ResultDomain<TbCrontabTaskMeta>
*/
@PostMapping("/page")
public ResultDomain<TbCrontabTaskMeta> getTaskMetaPage(@RequestBody PageRequest<TbCrontabTaskMeta> pageRequest) {
return taskMetaService.getTaskMetaPage(pageRequest);
}
}

View File

@@ -0,0 +1,45 @@
package org.xyzh.crontab.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.xyzh.common.dto.crontab.TbCrontabEmailDefault;
/**
* @description 定时任务邮件通知默认接收人访问层
* @filename EmailDefaultMapper.java
* @author yslg
* @copyright xyzh
* @since 2025-11-18
*/
@Mapper
public interface EmailDefaultMapper extends BaseMapper<TbCrontabEmailDefault> {
/**
* @description 插入默认接收人
*/
int insertDefault(@Param("emailDefault") TbCrontabEmailDefault emailDefault);
/**
* @description 更新默认接收人
*/
int updateDefault(@Param("emailDefault") TbCrontabEmailDefault emailDefault);
/**
* @description 删除默认接收人(逻辑删除)
*/
int deleteDefault(@Param("defaultId") String defaultId);
/**
* @description 根据defaultId查询
*/
TbCrontabEmailDefault selectDefaultById(@Param("defaultId") String defaultId);
/**
* @description 根据metaId查询
*/
List<TbCrontabEmailDefault> selectDefaultByMetaId(@Param("metaId") String metaId);
}

View File

@@ -0,0 +1,66 @@
package org.xyzh.crontab.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.dto.crontab.TbCrontabEmailRecipient;
import java.util.List;
/**
* @description 定时任务邮件接收人访问层
* @filename EmailRecipientMapper.java
* @author yslg
* @copyright xyzh
* @since 2025-11-18
*/
@Mapper
public interface EmailRecipientMapper extends BaseMapper<TbCrontabEmailRecipient> {
/**
* @description 插入邮件接收人
*/
int insertRecipient(@Param("recipient") TbCrontabEmailRecipient recipient);
/**
* @description 批量插入邮件接收人
*/
int batchInsertRecipient(@Param("recipients") List<TbCrontabEmailRecipient> recipients);
/**
* @description 更新邮件接收人
*/
int updateRecipient(@Param("recipient") TbCrontabEmailRecipient recipient);
/**
* @description 删除邮件接收人(逻辑删除)
*/
int deleteRecipient(@Param("recipientId") String recipientId);
/**
* @description 根据接收人ID查询
*/
TbCrontabEmailRecipient selectRecipientById(@Param("recipientId") String recipientId);
/**
* @description 根据任务ID查询接收人列表
*/
List<TbCrontabEmailRecipient> selectRecipientsByTaskId(@Param("taskId") String taskId);
/**
* @description 分页查询邮件接收人
*/
List<TbCrontabEmailRecipient> selectRecipientPage(@Param("filter") TbCrontabEmailRecipient filter, @Param("pageParam") PageParam pageParam);
/**
* @description 查询邮件接收人总数
*/
int countSelectRecipient(@Param("filter") TbCrontabEmailRecipient filter);
/**
* @description 删除任务的所有接收人
*/
int deleteRecipientsByTaskId(@Param("taskId") String taskId);
}

View File

@@ -0,0 +1,65 @@
package org.xyzh.crontab.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.dto.crontab.TbCrontabTaskMeta;
import java.util.List;
/**
* @description 定时任务元数据访问层
* @filename TaskMetaMapper.java
* @author yslg
* @copyright xyzh
* @since 2025-11-18
*/
@Mapper
public interface TaskMetaMapper extends BaseMapper<TbCrontabTaskMeta> {
/**
* @description 插入任务元数据
*/
int insertTaskMeta(@Param("taskMeta") TbCrontabTaskMeta taskMeta);
/**
* @description 更新任务元数据
*/
int updateTaskMeta(@Param("taskMeta") TbCrontabTaskMeta taskMeta);
/**
* @description 删除任务元数据(逻辑删除)
*/
int deleteTaskMeta(@Param("metaId") String metaId);
/**
* @description 根据元数据ID查询
*/
TbCrontabTaskMeta selectTaskMetaById(@Param("metaId") String metaId);
/**
* @description 根据任务ID查询
*/
TbCrontabTaskMeta selectTaskMetaByTaskId(@Param("taskId") String taskId);
/**
* @description 查询所有任务元数据
*/
List<TbCrontabTaskMeta> selectAllTaskMeta();
/**
* @description 根据分类查询任务元数据
*/
List<TbCrontabTaskMeta> selectTaskMetaByCategory(@Param("category") String category);
/**
* @description 分页查询任务元数据
*/
List<TbCrontabTaskMeta> selectTaskMetaPage(@Param("filter") TbCrontabTaskMeta filter, @Param("pageParam") PageParam pageParam);
/**
* @description 查询任务元数据总数
*/
int countSelectTaskMeta(@Param("filter") TbCrontabTaskMeta filter);
}

View File

@@ -157,9 +157,12 @@ public class TaskExecutor {
Map<String, Object> params = JSON.parseObject(methodParams,
new TypeReference<Map<String, Object>>(){});
// 注入taskIdlogId
// 注入taskIdlogId和metaId
params.put("taskId", task.getTaskId());
params.put("logId", log.getID());
if (task.getMetaId() != null) {
params.put("metaId", task.getMetaId());
}
taskParams.setParams(params);

View File

@@ -7,9 +7,14 @@ import org.springframework.scheduling.support.CronExpression;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.xyzh.api.crontab.CrontabService;
import org.xyzh.api.crontab.EmailDefaultService;
import org.xyzh.api.crontab.EmailRecipientService;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.core.page.PageDomain;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.dto.crontab.CreateTaskRequest;
import org.xyzh.common.dto.crontab.TbCrontabEmailDefault;
import org.xyzh.common.dto.crontab.TbCrontabEmailRecipient;
import org.xyzh.common.dto.crontab.TbCrontabTask;
import org.xyzh.common.dto.crontab.TbCrontabLog;
import org.xyzh.common.utils.IDUtils;
@@ -50,6 +55,12 @@ public class CrontabServiceImpl implements CrontabService {
@Autowired
private ResourcePermissionService resourcePermissionService;
@Autowired
private EmailDefaultService emailDefaultService;
@Autowired
private EmailRecipientService emailRecipientService;
// ----------------定时任务管理--------------------------------
@Override
@@ -115,6 +126,101 @@ public class CrontabServiceImpl implements CrontabService {
return resultDomain;
}
@Override
@Transactional(rollbackFor = Exception.class)
public ResultDomain<TbCrontabTask> createTaskWithRecipients(CreateTaskRequest request) {
ResultDomain<TbCrontabTask> resultDomain = new ResultDomain<>();
try {
TbCrontabTask task = request.getTask();
// 1. 创建任务
ResultDomain<TbCrontabTask> createResult = createTask(task);
if (!createResult.isSuccess()) {
return createResult;
}
String taskId = task.getTaskId();
String metaId = request.getMetaId();
// 3. 添加额外的接收人
if (request.getAdditionalRecipients() != null && !request.getAdditionalRecipients().isEmpty()) {
try {
for (CreateTaskRequest.RecipientUserInfo userInfo : request.getAdditionalRecipients()) {
TbCrontabEmailRecipient recipient = new TbCrontabEmailRecipient();
recipient.setTaskId(taskId);
recipient.setUserId(userInfo.getUserId());
recipient.setEmail(userInfo.getUserEmail());
recipient.setName(userInfo.getUsername());
recipient.setCreator(task.getCreator());
emailRecipientService.createRecipient(recipient);
}
logger.info("为任务{}添加了{}个额外接收人", taskId, request.getAdditionalRecipients().size());
} catch (Exception e) {
logger.error("添加额外接收人异常,但不影响任务创建: {}", e.getMessage(), e);
}
}
resultDomain.success("创建任务并绑定接收人成功", task);
} catch (Exception e) {
logger.error("创建任务并绑定接收人异常: ", e);
resultDomain.fail("创建任务并绑定接收人异常: " + e.getMessage());
}
return resultDomain;
}
@Override
@Transactional(rollbackFor = Exception.class)
public ResultDomain<TbCrontabTask> updateTaskWithRecipients(CreateTaskRequest request) {
ResultDomain<TbCrontabTask> resultDomain = new ResultDomain<>();
try {
TbCrontabTask task = request.getTask();
// 1. 更新任务
ResultDomain<TbCrontabTask> updateResult = updateTask(task);
if (!updateResult.isSuccess()) {
return updateResult;
}
String taskId = task.getTaskId();
String metaId = request.getMetaId();
// 2. 先删除该任务的旧接收人
try {
emailRecipientService.deleteRecipientsByTaskId(taskId);
logger.info("已删除任务{}的旧接收人配置", taskId);
} catch (Exception e) {
logger.error("删除旧接收人异常: {}", e.getMessage(), e);
}
// 4. 添加额外的接收人
if (request.getAdditionalRecipients() != null && !request.getAdditionalRecipients().isEmpty()) {
try {
for (CreateTaskRequest.RecipientUserInfo userInfo : request.getAdditionalRecipients()) {
TbCrontabEmailRecipient recipient = new TbCrontabEmailRecipient();
recipient.setTaskId(taskId);
recipient.setUserId(userInfo.getUserId());
recipient.setEmail(userInfo.getUserEmail());
recipient.setName(userInfo.getUsername());
recipient.setUpdater(task.getUpdater());
emailRecipientService.createRecipient(recipient);
}
logger.info("为任务{}添加了{}个额外接收人", taskId, request.getAdditionalRecipients().size());
} catch (Exception e) {
logger.error("添加额外接收人异常,但不影响任务更新: {}", e.getMessage(), e);
}
}
resultDomain.success("更新任务并更新接收人成功", task);
} catch (Exception e) {
logger.error("更新任务并更新接收人异常: ", e);
resultDomain.fail("更新任务并更新接收人异常: " + e.getMessage());
}
return resultDomain;
}
@Override
@Transactional(rollbackFor = Exception.class)
public ResultDomain<TbCrontabTask> updateTask(TbCrontabTask task) {

View File

@@ -0,0 +1,129 @@
package org.xyzh.crontab.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.xyzh.api.crontab.EmailDefaultService;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.dto.crontab.TbCrontabEmailDefault;
import org.xyzh.common.utils.IDUtils;
import org.xyzh.crontab.mapper.EmailDefaultMapper;
import java.util.Date;
import java.util.List;
/**
* @description 定时任务邮件通知默认接收人服务实现类
* @filename EmailDefaultServiceImpl.java
* @author yslg
* @copyright xyzh
* @since 2025-11-18
*/
@Service
public class EmailDefaultServiceImpl implements EmailDefaultService {
private static final Logger logger = LoggerFactory.getLogger(EmailDefaultServiceImpl.class);
@Autowired
private EmailDefaultMapper emailDefaultMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public ResultDomain<TbCrontabEmailDefault> createDefault(TbCrontabEmailDefault emailDefault) {
ResultDomain<TbCrontabEmailDefault> resultDomain = new ResultDomain<>();
try {
// 生成ID
emailDefault.setID(IDUtils.generateID());
if (emailDefault.getDefaultId() == null || emailDefault.getDefaultId().isEmpty()) {
emailDefault.setDefaultId(IDUtils.generateID());
}
emailDefault.setCreateTime(new Date());
emailDefault.setDeleted(false);
int count = emailDefaultMapper.insertDefault(emailDefault);
if (count > 0) {
resultDomain.success("创建默认接收人成功", emailDefault);
} else {
resultDomain.fail("创建默认接收人失败");
}
} catch (Exception e) {
logger.error("创建默认接收人异常: {}", e.getMessage(), e);
resultDomain.fail("创建默认接收人失败: " + e.getMessage());
}
return resultDomain;
}
@Override
@Transactional(rollbackFor = Exception.class)
public ResultDomain<TbCrontabEmailDefault> updateDefault(TbCrontabEmailDefault emailDefault) {
ResultDomain<TbCrontabEmailDefault> resultDomain = new ResultDomain<>();
try {
emailDefault.setUpdateTime(new Date());
int count = emailDefaultMapper.updateDefault(emailDefault);
if (count > 0) {
resultDomain.success("更新默认接收人成功", emailDefault);
} else {
resultDomain.fail("更新默认接收人失败");
}
} catch (Exception e) {
logger.error("更新默认接收人异常: {}", e.getMessage(), e);
resultDomain.fail("更新默认接收人失败: " + e.getMessage());
}
return resultDomain;
}
@Override
@Transactional(rollbackFor = Exception.class)
public ResultDomain<Boolean> deleteDefault(String defaultId) {
ResultDomain<Boolean> resultDomain = new ResultDomain<>();
try {
int count = emailDefaultMapper.deleteDefault(defaultId);
if (count > 0) {
resultDomain.success("删除默认接收人成功", true);
} else {
resultDomain.fail("删除默认接收人失败");
}
} catch (Exception e) {
logger.error("删除默认接收人异常: {}", e.getMessage(), e);
resultDomain.fail("删除默认接收人失败: " + e.getMessage());
}
return resultDomain;
}
@Override
public ResultDomain<TbCrontabEmailDefault> getDefaultById(String defaultId) {
ResultDomain<TbCrontabEmailDefault> resultDomain = new ResultDomain<>();
try {
TbCrontabEmailDefault emailDefault = emailDefaultMapper.selectDefaultById(defaultId);
if (emailDefault != null) {
resultDomain.success("查询默认接收人成功", emailDefault);
} else {
resultDomain.fail("默认接收人不存在");
}
} catch (Exception e) {
logger.error("查询默认接收人异常: {}", e.getMessage(), e);
resultDomain.fail("查询默认接收人失败: " + e.getMessage());
}
return resultDomain;
}
@Override
public ResultDomain<TbCrontabEmailDefault> getDefaultByMetaId(String metaId) {
ResultDomain<TbCrontabEmailDefault> resultDomain = new ResultDomain<>();
try {
List<TbCrontabEmailDefault> emailDefault = emailDefaultMapper.selectDefaultByMetaId(metaId);
if (emailDefault != null) {
resultDomain.success("查询默认接收人成功", emailDefault);
} else {
resultDomain.fail("该任务元数据未配置默认接收人");
}
} catch (Exception e) {
logger.error("查询默认接收人异常: {}", e.getMessage(), e);
resultDomain.fail("查询默认接收人失败: " + e.getMessage());
}
return resultDomain;
}
}

View File

@@ -0,0 +1,190 @@
package org.xyzh.crontab.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.xyzh.api.crontab.EmailRecipientService;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.core.page.PageDomain;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.core.page.PageRequest;
import org.xyzh.common.dto.crontab.TbCrontabEmailRecipient;
import org.xyzh.common.utils.IDUtils;
import org.xyzh.crontab.mapper.EmailRecipientMapper;
import java.util.Date;
import java.util.List;
/**
* @description 定时任务邮件接收人服务实现类
* @filename EmailRecipientServiceImpl.java
* @author yslg
* @copyright xyzh
* @since 2025-11-18
*/
@Service
public class EmailRecipientServiceImpl implements EmailRecipientService {
private static final Logger logger = LoggerFactory.getLogger(EmailRecipientServiceImpl.class);
@Autowired
private EmailRecipientMapper emailRecipientMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public ResultDomain<TbCrontabEmailRecipient> createRecipient(TbCrontabEmailRecipient recipient) {
ResultDomain<TbCrontabEmailRecipient> resultDomain = new ResultDomain<>();
try {
// 生成ID
recipient.setID(IDUtils.generateID());
if (recipient.getRecipientId() == null || recipient.getRecipientId().isEmpty()) {
recipient.setRecipientId(IDUtils.generateID());
}
recipient.setCreateTime(new Date());
recipient.setDeleted(false);
int count = emailRecipientMapper.insertRecipient(recipient);
if (count > 0) {
resultDomain.success("创建邮件接收人成功", recipient);
} else {
resultDomain.fail("创建邮件接收人失败");
}
} catch (Exception e) {
logger.error("创建邮件接收人异常: {}", e.getMessage(), e);
resultDomain.fail("创建邮件接收人失败: " + e.getMessage());
}
return resultDomain;
}
@Override
@Transactional(rollbackFor = Exception.class)
public ResultDomain<Boolean> batchCreateRecipient(List<TbCrontabEmailRecipient> recipients) {
ResultDomain<Boolean> resultDomain = new ResultDomain<>();
try {
for (TbCrontabEmailRecipient recipient : recipients) {
recipient.setID(IDUtils.generateID());
if (recipient.getRecipientId() == null || recipient.getRecipientId().isEmpty()) {
recipient.setRecipientId(IDUtils.generateID());
}
recipient.setCreateTime(new Date());
recipient.setDeleted(false);
}
int count = emailRecipientMapper.batchInsertRecipient(recipients);
if (count > 0) {
resultDomain.setSuccess(true);
resultDomain.setMessage("批量创建邮件接收人成功");
} else {
resultDomain.fail("批量创建邮件接收人失败");
}
} catch (Exception e) {
logger.error("批量创建邮件接收人异常: {}", e.getMessage(), e);
resultDomain.fail("批量创建邮件接收人失败: " + e.getMessage());
}
return resultDomain;
}
@Override
@Transactional(rollbackFor = Exception.class)
public ResultDomain<TbCrontabEmailRecipient> updateRecipient(TbCrontabEmailRecipient recipient) {
ResultDomain<TbCrontabEmailRecipient> resultDomain = new ResultDomain<>();
try {
recipient.setUpdateTime(new Date());
int count = emailRecipientMapper.updateRecipient(recipient);
if (count > 0) {
resultDomain.success("更新邮件接收人成功", recipient);
} else {
resultDomain.fail("更新邮件接收人失败");
}
} catch (Exception e) {
logger.error("更新邮件接收人异常: {}", e.getMessage(), e);
resultDomain.fail("更新邮件接收人失败: " + e.getMessage());
}
return resultDomain;
}
@Override
@Transactional(rollbackFor = Exception.class)
public ResultDomain<Boolean> deleteRecipient(String recipientId) {
ResultDomain<Boolean> resultDomain = new ResultDomain<>();
try {
int count = emailRecipientMapper.deleteRecipient(recipientId);
if (count > 0) {
resultDomain.success("删除邮件接收人成功", true);
} else {
resultDomain.fail("删除邮件接收人失败");
}
} catch (Exception e) {
logger.error("删除邮件接收人异常: {}", e.getMessage(), e);
resultDomain.fail("删除邮件接收人失败: " + e.getMessage());
}
return resultDomain;
}
@Override
public ResultDomain<TbCrontabEmailRecipient> getRecipientById(String recipientId) {
ResultDomain<TbCrontabEmailRecipient> resultDomain = new ResultDomain<>();
try {
TbCrontabEmailRecipient recipient = emailRecipientMapper.selectRecipientById(recipientId);
if (recipient != null) {
resultDomain.success("查询邮件接收人成功", recipient);
} else {
resultDomain.fail("邮件接收人不存在");
}
} catch (Exception e) {
logger.error("查询邮件接收人异常: {}", e.getMessage(), e);
resultDomain.fail("查询邮件接收人失败: " + e.getMessage());
}
return resultDomain;
}
@Override
public ResultDomain<TbCrontabEmailRecipient> getRecipientsByTaskId(String taskId) {
ResultDomain<TbCrontabEmailRecipient> resultDomain = new ResultDomain<>();
try {
List<TbCrontabEmailRecipient> list = emailRecipientMapper.selectRecipientsByTaskId(taskId);
resultDomain.success("查询邮件接收人列表成功", list);
} catch (Exception e) {
logger.error("查询邮件接收人列表异常: {}", e.getMessage(), e);
resultDomain.fail("查询邮件接收人列表失败: " + e.getMessage());
}
return resultDomain;
}
@Override
public ResultDomain<TbCrontabEmailRecipient> getRecipientPage(PageRequest<TbCrontabEmailRecipient> request) {
ResultDomain<TbCrontabEmailRecipient> resultDomain = new ResultDomain<>();
try {
PageParam pageParam = request.getPageParam();
List<TbCrontabEmailRecipient> list = emailRecipientMapper.selectRecipientPage(request.getFilter(), pageParam);
int total = emailRecipientMapper.countSelectRecipient(request.getFilter());
PageDomain<TbCrontabEmailRecipient> pageDomain = new PageDomain<>();
pageDomain.setPageParam(pageParam);
pageParam.setTotalElements(total);
pageDomain.setDataList(list);
resultDomain.success("分页查询邮件接收人成功", pageDomain);
} catch (Exception e) {
logger.error("分页查询邮件接收人异常: {}", e.getMessage(), e);
resultDomain.fail("分页查询邮件接收人失败: " + e.getMessage());
}
return resultDomain;
}
@Override
@Transactional(rollbackFor = Exception.class)
public ResultDomain<Boolean> deleteRecipientsByTaskId(String taskId) {
ResultDomain<Boolean> resultDomain = new ResultDomain<>();
try {
int count = emailRecipientMapper.deleteRecipientsByTaskId(taskId);
resultDomain.success("删除任务的所有接收人成功,共" + count + "", true);
} catch (Exception e) {
logger.error("删除任务的所有接收人异常: {}", e.getMessage(), e);
resultDomain.fail("删除任务的所有接收人失败: " + e.getMessage());
}
return resultDomain;
}
}

View File

@@ -0,0 +1,187 @@
package org.xyzh.crontab.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.xyzh.api.crontab.TaskMetaService;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.core.page.PageDomain;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.core.page.PageRequest;
import org.xyzh.common.dto.crontab.TbCrontabTaskMeta;
import org.xyzh.common.utils.IDUtils;
import org.xyzh.crontab.mapper.TaskMetaMapper;
import java.util.Date;
import java.util.List;
/**
* @description 定时任务元数据服务实现类
* @filename TaskMetaServiceImpl.java
* @author yslg
* @copyright xyzh
* @since 2025-11-18
*/
@Service
public class TaskMetaServiceImpl implements TaskMetaService {
private static final Logger logger = LoggerFactory.getLogger(TaskMetaServiceImpl.class);
@Autowired
private TaskMetaMapper taskMetaMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public ResultDomain<TbCrontabTaskMeta> createTaskMeta(TbCrontabTaskMeta taskMeta) {
ResultDomain<TbCrontabTaskMeta> resultDomain = new ResultDomain<>();
try {
// 检查meta_id是否已存在
TbCrontabTaskMeta existing = taskMetaMapper.selectTaskMetaById(taskMeta.getMetaId());
if (existing != null) {
resultDomain.fail("任务元数据ID已存在: " + taskMeta.getMetaId());
return resultDomain;
}
// 生成ID
taskMeta.setID(IDUtils.generateID());
taskMeta.setCreateTime(new Date());
taskMeta.setDeleted(false);
// 默认值
if (taskMeta.getSortOrder() == null) {
taskMeta.setSortOrder(0);
}
int count = taskMetaMapper.insertTaskMeta(taskMeta);
if (count > 0) {
resultDomain.success("创建任务元数据成功", taskMeta);
} else {
resultDomain.fail("创建任务元数据失败");
}
} catch (Exception e) {
logger.error("创建任务元数据异常: {}", e.getMessage(), e);
resultDomain.fail("创建任务元数据失败: " + e.getMessage());
}
return resultDomain;
}
@Override
@Transactional(rollbackFor = Exception.class)
public ResultDomain<TbCrontabTaskMeta> updateTaskMeta(TbCrontabTaskMeta taskMeta) {
ResultDomain<TbCrontabTaskMeta> resultDomain = new ResultDomain<>();
try {
taskMeta.setUpdateTime(new Date());
int count = taskMetaMapper.updateTaskMeta(taskMeta);
if (count > 0) {
resultDomain.success("更新任务元数据成功", taskMeta);
} else {
resultDomain.fail("更新任务元数据失败");
}
} catch (Exception e) {
logger.error("更新任务元数据异常: {}", e.getMessage(), e);
resultDomain.fail("更新任务元数据失败: " + e.getMessage());
}
return resultDomain;
}
@Override
@Transactional(rollbackFor = Exception.class)
public ResultDomain<Boolean> deleteTaskMeta(String metaId) {
ResultDomain<Boolean> resultDomain = new ResultDomain<>();
try {
int count = taskMetaMapper.deleteTaskMeta(metaId);
if (count > 0) {
resultDomain.success("删除任务元数据成功", true);
} else {
resultDomain.fail("删除任务元数据失败");
}
} catch (Exception e) {
logger.error("删除任务元数据异常: {}", e.getMessage(), e);
resultDomain.fail("删除任务元数据失败: " + e.getMessage());
}
return resultDomain;
}
@Override
public ResultDomain<TbCrontabTaskMeta> getTaskMetaById(String metaId) {
ResultDomain<TbCrontabTaskMeta> resultDomain = new ResultDomain<>();
try {
TbCrontabTaskMeta taskMeta = taskMetaMapper.selectTaskMetaById(metaId);
if (taskMeta != null) {
resultDomain.success("查询任务元数据成功", taskMeta);
} else {
resultDomain.fail("任务元数据不存在");
}
} catch (Exception e) {
logger.error("查询任务元数据异常: {}", e.getMessage(), e);
resultDomain.fail("查询任务元数据失败: " + e.getMessage());
}
return resultDomain;
}
@Override
public ResultDomain<TbCrontabTaskMeta> getTaskMetaByTaskId(String taskId) {
ResultDomain<TbCrontabTaskMeta> resultDomain = new ResultDomain<>();
try {
TbCrontabTaskMeta taskMeta = taskMetaMapper.selectTaskMetaByTaskId(taskId);
if (taskMeta != null) {
resultDomain.success("查询任务元数据成功", taskMeta);
} else {
resultDomain.fail("任务元数据不存在");
}
} catch (Exception e) {
logger.error("查询任务元数据异常: {}", e.getMessage(), e);
resultDomain.fail("查询任务元数据失败: " + e.getMessage());
}
return resultDomain;
}
@Override
public ResultDomain<TbCrontabTaskMeta> getAllTaskMeta() {
ResultDomain<TbCrontabTaskMeta> resultDomain = new ResultDomain<>();
try {
List<TbCrontabTaskMeta> list = taskMetaMapper.selectAllTaskMeta();
resultDomain.success("查询所有任务元数据成功", list);
} catch (Exception e) {
logger.error("查询所有任务元数据异常: {}", e.getMessage(), e);
resultDomain.fail("查询所有任务元数据失败: " + e.getMessage());
}
return resultDomain;
}
@Override
public ResultDomain<TbCrontabTaskMeta> getTaskMetaByCategory(String category) {
ResultDomain<TbCrontabTaskMeta> resultDomain = new ResultDomain<>();
try {
List<TbCrontabTaskMeta> list = taskMetaMapper.selectTaskMetaByCategory(category);
resultDomain.success("查询分类任务元数据成功", list);
} catch (Exception e) {
logger.error("查询分类任务元数据异常: {}", e.getMessage(), e);
resultDomain.fail("查询分类任务元数据失败: " + e.getMessage());
}
return resultDomain;
}
@Override
public ResultDomain<TbCrontabTaskMeta> getTaskMetaPage(PageRequest<TbCrontabTaskMeta> request) {
ResultDomain<TbCrontabTaskMeta> resultDomain = new ResultDomain<>();
try {
PageParam pageParam = request.getPageParam();
List<TbCrontabTaskMeta> list = taskMetaMapper.selectTaskMetaPage(request.getFilter(), pageParam);
int total = taskMetaMapper.countSelectTaskMeta(request.getFilter());
PageDomain<TbCrontabTaskMeta> pageDomain = new PageDomain<>();
pageDomain.setPageParam(pageParam);
pageParam.setTotalElements(total);
pageDomain.setDataList(list);
resultDomain.success("分页查询任务元数据成功", pageDomain);
} catch (Exception e) {
logger.error("分页查询任务元数据异常: {}", e.getMessage(), e);
resultDomain.fail("分页查询任务元数据失败: " + e.getMessage());
}
return resultDomain;
}
}

View File

@@ -1,14 +1,14 @@
package org.xyzh.crontab.task;
import org.springframework.beans.factory.annotation.Autowired;
import org.xyzh.crontab.config.CrawlerProperties;
import org.xyzh.api.system.config.SysConfigService;
import org.xyzh.crontab.pojo.TaskParams;
import java.util.ArrayList;
import java.util.List;
/**
* @description Python命令任务抽象类
* @description Python命令任务抽象类(从数据库获取配置)
* @filename PythonCommandTask.java
* @author yslg
* @copyright xyzh
@@ -17,23 +17,36 @@ import java.util.List;
public abstract class PythonCommandTask extends CommandTask {
@Autowired
protected CrawlerProperties crawlerProperties;
protected SysConfigService sysConfigService;
/**
* 获取Python可执行文件路径
* 获取Python可执行文件路径(从数据库系统配置获取)
*/
protected String getPythonPath() {
return crawlerProperties.getPythonPath() != null
? crawlerProperties.getPythonPath()
: "python";
try {
String value = sysConfigService.getStringConfig("crawler.pythonPath");
if (value != null && !value.isEmpty()) {
return value;
}
} catch (Exception e) {
logger.warn("获取Python路径配置失败使用默认值: {}", e.getMessage());
}
return "python"; // 默认值
}
/**
* 获取脚本基础路径
* 获取脚本基础路径(从数据库系统配置获取)
*/
protected String getScriptBasePath() {
return crawlerProperties.getBasePath() != null
? crawlerProperties.getBasePath()
: "../schoolNewsCrawler";
try {
String value = sysConfigService.getStringConfig("crawler.basePath");
if (value != null && !value.isEmpty()) {
return value;
}
} catch (Exception e) {
logger.warn("获取脚本基础路径配置失败,使用默认值: {}", e.getMessage());
}
return "../schoolNewsCrawler"; // 默认值
}
/**

View File

@@ -4,11 +4,19 @@ import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.xyzh.api.crontab.CrontabService;
import org.xyzh.api.crontab.DataCollectionItemService;
import org.xyzh.api.crontab.EmailDefaultService;
import org.xyzh.api.crontab.EmailRecipientService;
import org.xyzh.api.crontab.TaskMetaService;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.dto.crontab.TbCrontabEmailDefault;
import org.xyzh.common.dto.crontab.TbCrontabEmailRecipient;
import org.xyzh.common.dto.crontab.TbCrontabTask;
import org.xyzh.common.dto.crontab.TbCrontabTaskMeta;
import org.xyzh.common.dto.crontab.TbDataCollectionItem;
import org.xyzh.common.utils.EmailUtils;
import org.xyzh.common.utils.IDUtils;
import org.xyzh.crontab.config.CrontabProperties;
import org.xyzh.crontab.pojo.TaskParams;
import org.xyzh.crontab.task.PythonCommandTask;
@@ -18,9 +26,9 @@ import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @description 新闻爬虫定时任务
@@ -32,11 +40,23 @@ import java.util.Map;
@Component("newsCrewerTask")
public class NewsCrawlerTask extends PythonCommandTask {
@Autowired
private CrontabProperties crontabProperties;
@Autowired
private DataCollectionItemService itemService;
@Autowired
private TaskMetaService taskMetaService;
@Autowired
private CrontabService crontabService;
@Autowired
private EmailDefaultService emailDefaultService;
@Autowired
private EmailRecipientService emailRecipientService;
@Autowired
private EmailUtils emailUtils;
/**
* 构建Python脚本参数
@@ -45,11 +65,23 @@ public class NewsCrawlerTask extends PythonCommandTask {
protected List<String> buildPythonArgs(TaskParams taskParams) throws Exception {
List<String> args = new ArrayList<>();
// 1. 从params获取scriptPath
String scriptPath = taskParams.getParamAsString("scriptPath");
if (scriptPath == null || scriptPath.isEmpty()) {
throw new Exception("scriptPath参数缺失");
// 1. 从数据库读取scriptPath通过metaId
String metaId = taskParams.getParamAsString("metaId");
if (metaId == null || metaId.isEmpty()) {
throw new Exception("metaId参数缺失无法获取scriptPath");
}
ResultDomain<TbCrontabTaskMeta> metaResult = taskMetaService.getTaskMetaById(metaId);
if (!metaResult.isSuccess() || metaResult.getData() == null) {
throw new Exception("未找到任务元数据: metaId=" + metaId);
}
String scriptPath = metaResult.getData().getScriptPath();
if (scriptPath == null || scriptPath.isEmpty()) {
throw new Exception("任务元数据中scriptPath为空: metaId=" + metaId);
}
logger.info("从数据库读取scriptPath: {}, metaId: {}", scriptPath, metaId);
// 2. 生成输出文件名
String timestamp = String.valueOf(System.currentTimeMillis());
@@ -70,7 +102,7 @@ public class NewsCrawlerTask extends PythonCommandTask {
Object value = entry.getValue();
// 跳过特殊参数
if (key.startsWith("_") || key.equals("scriptPath") ||
if (key.startsWith("_") || key.equals("metaId") ||
key.equals("taskId") || key.equals("logId")) {
continue;
}
@@ -130,7 +162,12 @@ public class NewsCrawlerTask extends PythonCommandTask {
// 保存新闻数据到数据库
if (taskId != null && !taskId.isEmpty() && logId != null && !logId.isEmpty()) {
saveNewsToDatabase(newsList, taskId, logId);
ResultDomain<TbCrontabTask> taskResult = crontabService.getTaskById(taskId);
saveNewsToDatabase(newsList, taskResult.getData(), logId);
// 发送邮件通知
sendEmailNotification(taskId, taskResult.getData(), newsList);
} else {
logger.warn("未提供任务ID或日志ID跳过数据保存");
}
@@ -139,14 +176,20 @@ public class NewsCrawlerTask extends PythonCommandTask {
/**
* 将新闻数据保存到数据库
*/
private void saveNewsToDatabase(List<ArticleStruct> newsList, String taskId, String logId) {
private void saveNewsToDatabase(List<ArticleStruct> newsList, TbCrontabTask task, String logId) {
String taskId = task.getTaskId();
logger.info("开始保存 {} 条新闻到数据库任务ID: {}日志ID: {}", newsList.size(), taskId, logId);
try {
List<TbDataCollectionItem> itemList = new ArrayList<>();
ResultDomain<TbCrontabTaskMeta> metaResult = taskMetaService.getTaskMetaByTaskId(taskId);
if (!metaResult.isSuccess() || metaResult.getData() == null) {
throw new Exception("未找到任务元数据: taskId=" + taskId);
}
TbCrontabTaskMeta taskMeta = metaResult.getData();
Date now = new Date();
SimpleDateFormat parser = new SimpleDateFormat("yyyy年MM月dd日HH:mm");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (ArticleStruct news : newsList) {
@@ -209,9 +252,155 @@ public class NewsCrawlerTask extends PythonCommandTask {
} else {
logger.warn("没有有效的新闻数据需要保存");
}
if (taskMeta.getAutoPublish()){
publishNewsToArticle(newsList, task, logId);
}
} catch (Exception e) {
logger.error("保存新闻数据到数据库异常: ", e);
}
}
/**
* 发送邮件通知
*/
private void sendEmailNotification(String taskId, TbCrontabTask task, List<ArticleStruct> newsList) {
try {
List<String> recipients = new ArrayList<>();
// 2. 如果使用默认接收人,查询默认接收人列表
if (Boolean.TRUE.equals(task.getDefaultRecipient()) && task.getMetaId() != null) {
ResultDomain<TbCrontabEmailDefault> defaultResult = emailDefaultService.getDefaultByMetaId(task.getMetaId());
if (defaultResult.isSuccess() && defaultResult.getDataList() != null) {
for (TbCrontabEmailDefault defaultRecipient : defaultResult.getDataList()) {
if (defaultRecipient.getUserEmail() != null && !defaultRecipient.getUserEmail().isEmpty()) {
recipients.add(defaultRecipient.getUserEmail());
}
}
}
}
// 3. 查询额外接收人
ResultDomain<TbCrontabEmailRecipient> recipientResult = emailRecipientService.getRecipientsByTaskId(taskId);
if (recipientResult.isSuccess() && recipientResult.getDataList() != null) {
for (TbCrontabEmailRecipient recipient : recipientResult.getDataList()) {
if (recipient.getEmail() != null && !recipient.getEmail().isEmpty()) {
recipients.add(recipient.getEmail());
}
}
}
// 4. 去重
recipients = recipients.stream().distinct().collect(Collectors.toList());
if (recipients.isEmpty()) {
logger.info("任务 {} 没有配置接收人,跳过邮件发送", task.getTaskName());
return;
}
// 5. 构建邮件内容
String subject = "【新闻爬虫通知】" + task.getTaskName() + " 执行完成";
String content = buildEmailContent(task.getTaskName(), newsList);
// 6. 发送邮件
int successCount = 0;
for (String email : recipients) {
if (emailUtils.sendHtmlEmail(email, subject, content)) {
successCount++;
}
}
logger.info("邮件发送完成,成功发送: {}/{},任务: {}", successCount, recipients.size(), task.getTaskName());
} catch (Exception e) {
logger.error("发送邮件通知异常,但不影响任务执行: ", e);
}
}
/**
* 构建邮件HTML内容
*/
private String buildEmailContent(String taskName, List<ArticleStruct> newsList) {
StringBuilder html = new StringBuilder();
html.append("<!DOCTYPE html>")
.append("<html>")
.append("<head>")
.append("<meta charset='UTF-8'>")
.append("<style>")
.append("body { font-family: 'Microsoft YaHei', Arial, sans-serif; background-color: #f5f5f5; margin: 0; padding: 20px; }")
.append(".container { max-width: 800px; margin: 0 auto; background-color: #ffffff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); overflow: hidden; }")
.append(".header { background: linear-gradient(135deg, #C62828 0%, #E53935 100%); padding: 30px; text-align: center; color: #ffffff; }")
.append(".header h1 { margin: 0; font-size: 24px; }")
.append(".content { padding: 30px; }")
.append(".summary { background-color: #f8f9fa; border-left: 4px solid #C62828; padding: 15px; margin: 20px 0; }")
.append(".news-list { margin-top: 20px; }")
.append(".news-item { border-bottom: 1px solid #e0e0e0; padding: 15px 0; }")
.append(".news-item:last-child { border-bottom: none; }")
.append(".news-title { font-size: 16px; font-weight: bold; color: #333; margin-bottom: 8px; }")
.append(".news-meta { font-size: 14px; color: #666; }")
.append(".news-link { color: #C62828; text-decoration: none; }")
.append(".footer { background-color: #f8f9fa; padding: 20px; text-align: center; color: #999; font-size: 12px; }")
.append("</style>")
.append("</head>")
.append("<body>")
.append("<div class='container'>")
.append("<div class='header'>")
.append("<h1>新闻爬虫执行通知</h1>")
.append("</div>")
.append("<div class='content'>");
// 摘要信息
html.append("<div class='summary'>")
.append("<p><strong>任务名称:</strong>").append(taskName).append("</p>")
.append("<p><strong>执行时间:</strong>").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())).append("</p>")
.append("<p><strong>爬取数量:</strong>").append(newsList.size()).append(" 条</p>")
.append("</div>");
// 新闻列表
html.append("<div class='news-list'>")
.append("<h3>爬取内容:</h3>");
int count = Math.min(newsList.size(), 10); // 最多显示10条
for (int i = 0; i < count; i++) {
ArticleStruct news = newsList.get(i);
html.append("<div class='news-item'>")
.append("<div class='news-title'>").append(news.getTitle() != null ? news.getTitle() : "无标题").append("</div>")
.append("<div class='news-meta'>")
.append("来源:").append(news.getSource() != null ? news.getSource() : "未知")
.append(" | ")
.append("发布时间:").append(news.getPublishTime() != null ? news.getPublishTime() : "未知");
if (news.getUrl() != null && !news.getUrl().isEmpty()) {
html.append(" | <a href='").append(news.getUrl()).append("' class='news-link' target='_blank'>查看原文</a>");
}
html.append("</div>")
.append("</div>");
}
if (newsList.size() > 10) {
html.append("<p style='text-align: center; color: #666; margin-top: 15px;'>")
.append("还有 ").append(newsList.size() - 10).append(" 条新闻未显示,请登录系统查看详情")
.append("</p>");
}
html.append("</div>"); // news-list
html.append("</div>"); // content
// 页脚
html.append("<div class='footer'>")
.append("<p>此邮件由系统自动发送,请勿回复</p>")
.append("<p>Copyright © 红色思政智能体平台</p>")
.append("</div>")
.append("</div>") // container
.append("</body>")
.append("</html>");
return html.toString();
}
// TODO 自动发布功能,把采集的数据发布到文章表
private void publishNewsToArticle(List<ArticleStruct> newsList, TbCrontabTask task, String logId) {
}
}

View File

@@ -47,5 +47,3 @@ crontab:
description: 是否是昨天
type: Boolean
value: true

View File

@@ -11,6 +11,8 @@
<result column="bean_name" property="beanName" />
<result column="method_name" property="methodName" />
<result column="method_params" property="methodParams" />
<result column="meta_id" property="metaId" />
<result column="default_recipient" property="defaultRecipient" />
<result column="cron_expression" property="cronExpression" />
<result column="status" property="status" />
<result column="description" property="description" />
@@ -26,7 +28,7 @@
<!-- 字段列表 -->
<sql id="Base_Column_List">
id, task_id, task_name, task_group, bean_name, method_name, method_params,
id, task_id, task_name, task_group, bean_name, method_name, method_params, meta_id, default_recipient,
cron_expression, status, description, concurrent, misfire_policy,
creator, updater, create_time, update_time, delete_time, deleted
</sql>
@@ -132,6 +134,8 @@
<if test="task.beanName != null">bean_name,</if>
<if test="task.methodName != null">method_name,</if>
<if test="task.methodParams != null">method_params,</if>
<if test="task.metaId != null">meta_id,</if>
<if test="task.defaultRecipient != null">default_recipient,</if>
<if test="task.cronExpression != null">cron_expression,</if>
<if test="task.status != null">status,</if>
<if test="task.description != null">description,</if>
@@ -150,6 +154,8 @@
<if test="task.beanName != null">#{task.beanName},</if>
<if test="task.methodName != null">#{task.methodName},</if>
<if test="task.methodParams != null">#{task.methodParams},</if>
<if test="task.metaId != null">#{task.metaId},</if>
<if test="task.defaultRecipient != null">#{task.defaultRecipient},</if>
<if test="task.cronExpression != null">#{task.cronExpression},</if>
<if test="task.status != null">#{task.status},</if>
<if test="task.description != null">#{task.description},</if>
@@ -170,6 +176,8 @@
<if test="task.beanName != null">bean_name = #{task.beanName},</if>
<if test="task.methodName != null">method_name = #{task.methodName},</if>
<if test="task.methodParams != null">method_params = #{task.methodParams},</if>
<if test="task.metaId != null">meta_id = #{task.metaId},</if>
<if test="task.defaultRecipient != null">default_recipient = #{task.defaultRecipient},</if>
<if test="task.cronExpression != null">cron_expression = #{task.cronExpression},</if>
<if test="task.status != null">status = #{task.status},</if>
<if test="task.description != null">description = #{task.description},</if>

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.xyzh.crontab.mapper.EmailDefaultMapper">
<!-- 结果映射 -->
<resultMap id="BaseResultMap" type="org.xyzh.common.dto.crontab.TbCrontabEmailDefault">
<id column="id" property="ID" />
<result column="default_id" property="defaultId" />
<result column="meta_id" property="metaId" />
<result column="user_id" property="userId" />
<result column="user_email" property="userEmail" />
<result column="username" property="username" />
<result column="creator" property="creator" />
<result column="updater" property="updater" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
<result column="delete_time" property="deleteTime" />
<result column="deleted" property="deleted" />
</resultMap>
<!-- 字段列表 -->
<sql id="Base_Column_List">
id, default_id, meta_id, user_id,
creator, updater, create_time, update_time, delete_time, deleted
</sql>
<!-- 插入默认接收人 -->
<insert id="insertDefault" parameterType="org.xyzh.common.dto.crontab.TbCrontabEmailDefault">
INSERT INTO tb_crontab_email_default (
id, default_id, meta_id, user_id, creator, create_time
) VALUES (
#{emailDefault.ID}, #{emailDefault.defaultId}, #{emailDefault.metaId},
#{emailDefault.userId}, #{emailDefault.creator}, NOW()
)
</insert>
<!-- 更新默认接收人 -->
<update id="updateDefault" parameterType="org.xyzh.common.dto.crontab.TbCrontabEmailDefault">
UPDATE tb_crontab_email_default
SET meta_id = #{emailDefault.metaId},
user_id = #{emailDefault.userId},
updater = #{emailDefault.updater},
update_time = NOW()
WHERE default_id = #{emailDefault.defaultId}
AND deleted = 0
</update>
<!-- 删除默认接收人(逻辑删除) -->
<update id="deleteDefault">
UPDATE tb_crontab_email_default
SET deleted = 1,
delete_time = NOW()
WHERE default_id = #{defaultId}
AND deleted = 0
</update>
<!-- 根据defaultId查询 -->
<select id="selectDefaultById" resultMap="BaseResultMap">
SELECT tced.id, tced.default_id, tced.meta_id, tced.user_id, tu.email as user_email, tu.username
FROM tb_crontab_email_default tced
LEFT JOIN tb_sys_user tu ON tced.user_id = tu.id
WHERE tced.default_id = #{defaultId}
AND tced.deleted = 0
</select>
<!-- 根据metaId查询 -->
<select id="selectDefaultByMetaId" resultMap="BaseResultMap">
SELECT tced.id, tced.default_id, tced.meta_id, tced.user_id, tu.email as user_email, tu.username
FROM tb_crontab_email_default tced
LEFT JOIN tb_sys_user tu ON tced.user_id = tu.id
WHERE tced.meta_id = #{metaId}
AND tced.deleted = 0
LIMIT 1
</select>
</mapper>

View File

@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.xyzh.crontab.mapper.EmailRecipientMapper">
<!-- 结果映射 -->
<resultMap id="BaseResultMap" type="org.xyzh.common.dto.crontab.TbCrontabEmailRecipient">
<id column="id" property="ID" />
<result column="recipient_id" property="recipientId" />
<result column="task_id" property="taskId" />
<result column="user_id" property="userId" />
<result column="email" property="email" />
<result column="name" property="name" />
<result column="creator" property="creator" />
<result column="updater" property="updater" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
<result column="delete_time" property="deleteTime" />
<result column="deleted" property="deleted" />
</resultMap>
<!-- 字段列表 -->
<sql id="Base_Column_List">
id, recipient_id, task_id, user_id, email, name,
creator, updater, create_time, update_time, delete_time, deleted
</sql>
<!-- 查询条件 -->
<sql id="Base_Where_Clause">
<where>
deleted = 0
<if test="filter.recipientId != null and filter.recipientId != ''">
AND recipient_id = #{filter.recipientId}
</if>
<if test="filter.taskId != null and filter.taskId != ''">
AND task_id = #{filter.taskId}
</if>
<if test="filter.userId != null and filter.userId != ''">
AND user_id = #{filter.userId}
</if>
<if test="filter.email != null and filter.email != ''">
AND email LIKE CONCAT('%', #{filter.email}, '%')
</if>
</where>
</sql>
<!-- 插入邮件接收人 -->
<insert id="insertRecipient" parameterType="org.xyzh.common.dto.crontab.TbCrontabEmailRecipient">
INSERT INTO tb_crontab_email_recipient (
id, recipient_id, task_id, user_id, email, name, creator, create_time
) VALUES (
#{recipient.ID}, #{recipient.recipientId}, #{recipient.taskId},
#{recipient.userId}, #{recipient.email}, #{recipient.name},
#{recipient.creator}, NOW()
)
</insert>
<!-- 批量插入邮件接收人 -->
<insert id="batchInsertRecipient">
INSERT INTO tb_crontab_email_recipient (
id, recipient_id, task_id, user_id, email, name, creator, create_time
) VALUES
<foreach collection="recipients" item="item" separator=",">
(#{item.ID}, #{item.recipientId}, #{item.taskId},
#{item.userId}, #{item.email}, #{item.name}, #{item.creator}, NOW())
</foreach>
</insert>
<!-- 更新邮件接收人 -->
<update id="updateRecipient" parameterType="org.xyzh.common.dto.crontab.TbCrontabEmailRecipient">
UPDATE tb_crontab_email_recipient
SET task_id = #{recipient.taskId},
user_id = #{recipient.userId},
email = #{recipient.email},
name = #{recipient.name},
updater = #{recipient.updater},
update_time = NOW()
WHERE recipient_id = #{recipient.recipientId}
AND deleted = 0
</update>
<!-- 删除邮件接收人(逻辑删除) -->
<update id="deleteRecipient">
UPDATE tb_crontab_email_recipient
SET deleted = 1,
delete_time = NOW()
WHERE recipient_id = #{recipientId}
AND deleted = 0
</update>
<!-- 根据ID查询 -->
<select id="selectRecipientById" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM tb_crontab_email_recipient
WHERE recipient_id = #{recipientId}
AND deleted = 0
</select>
<!-- 根据任务ID查询接收人列表 -->
<select id="selectRecipientsByTaskId" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM tb_crontab_email_recipient
WHERE task_id = #{taskId}
AND deleted = 0
ORDER BY create_time ASC
</select>
<!-- 查询所有接收人 -->
<select id="selectAllRecipients" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM tb_crontab_email_recipient
WHERE deleted = 0
ORDER BY create_time ASC
</select>
<!-- 分页查询 -->
<select id="selectRecipientPage" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM tb_crontab_email_recipient
<include refid="Base_Where_Clause" />
ORDER BY create_time DESC
LIMIT #{pageParam.offset}, #{pageParam.pageSize}
</select>
<!-- 查询总数 -->
<select id="countSelectRecipient" resultType="int">
SELECT COUNT(*)
FROM tb_crontab_email_recipient
<include refid="Base_Where_Clause" />
</select>
<!-- 删除任务的所有接收人 -->
<update id="deleteRecipientsByTaskId">
UPDATE tb_crontab_email_recipient
SET deleted = 1,
delete_time = NOW()
WHERE task_id = #{taskId}
AND deleted = 0
</update>
</mapper>

View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.xyzh.crontab.mapper.TaskMetaMapper">
<!-- 结果映射 -->
<resultMap id="BaseResultMap" type="org.xyzh.common.dto.crontab.TbCrontabTaskMeta">
<id column="id" property="ID" />
<result column="meta_id" property="metaId" />
<result column="name" property="name" />
<result column="description" property="description" />
<result column="category" property="category" />
<result column="bean_name" property="beanName" />
<result column="method_name" property="methodName" />
<result column="script_path" property="scriptPath" />
<result column="param_schema" property="paramSchema" />
<result column="auto_publish" property="autoPublish" />
<result column="sort_order" property="sortOrder" />
<result column="creator" property="creator" />
<result column="updater" property="updater" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
<result column="delete_time" property="deleteTime" />
<result column="deleted" property="deleted" />
</resultMap>
<!-- 字段列表 -->
<sql id="Base_Column_List">
id, meta_id, name, description, category, bean_name, method_name,
script_path, param_schema, auto_publish, sort_order,
creator, updater, create_time, update_time, delete_time, deleted
</sql>
<!-- 查询条件 -->
<sql id="Base_Where_Clause">
<where>
deleted = 0
<if test="filter.metaId != null and filter.metaId != ''">
AND meta_id = #{filter.metaId}
</if>
<if test="filter.name != null and filter.name != ''">
AND name LIKE CONCAT('%', #{filter.name}, '%')
</if>
<if test="filter.category != null and filter.category != ''">
AND category = #{filter.category}
</if>
</where>
</sql>
<!-- 插入任务元数据 -->
<insert id="insertTaskMeta" parameterType="org.xyzh.common.dto.crontab.TbCrontabTaskMeta">
INSERT INTO tb_crontab_task_meta (
id, meta_id, name, description, category, bean_name, method_name,
script_path, param_schema, auto_publish, sort_order, creator, create_time
) VALUES (
#{taskMeta.ID}, #{taskMeta.metaId}, #{taskMeta.name}, #{taskMeta.description},
#{taskMeta.category}, #{taskMeta.beanName}, #{taskMeta.methodName},
#{taskMeta.scriptPath}, #{taskMeta.paramSchema}, #{taskMeta.autoPublish}, #{taskMeta.sortOrder},
#{taskMeta.creator}, NOW()
)
</insert>
<!-- 更新任务元数据 -->
<update id="updateTaskMeta" parameterType="org.xyzh.common.dto.crontab.TbCrontabTaskMeta">
UPDATE tb_crontab_task_meta
SET name = #{taskMeta.name},
description = #{taskMeta.description},
category = #{taskMeta.category},
bean_name = #{taskMeta.beanName},
method_name = #{taskMeta.methodName},
script_path = #{taskMeta.scriptPath},
param_schema = #{taskMeta.paramSchema},
auto_publish = #{taskMeta.autoPublish},
sort_order = #{taskMeta.sortOrder},
updater = #{taskMeta.updater},
update_time = NOW()
WHERE meta_id = #{taskMeta.metaId}
AND deleted = 0
</update>
<!-- 删除任务元数据(逻辑删除) -->
<update id="deleteTaskMeta">
UPDATE tb_crontab_task_meta
SET deleted = 1,
delete_time = NOW()
WHERE meta_id = #{metaId}
AND deleted = 0
</update>
<!-- 根据ID查询 -->
<select id="selectTaskMetaById" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM tb_crontab_task_meta
WHERE meta_id = #{metaId}
AND deleted = 0
</select>
<!-- 根据TaskID查询 -->
<select id="selectTaskMetaByTaskId" resultMap="BaseResultMap">
SELECT tcte.*
FROM tb_crontab_task tct
LEFT JOIN tb_crontab_task_meta tcte ON tct.meta_id = tcte.meta_id
WHERE tct.task_id = #{taskId}
AND tcte.deleted = 0
</select>
<!-- 查询所有任务元数据 -->
<select id="selectAllTaskMeta" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM tb_crontab_task_meta
WHERE deleted = 0
ORDER BY sort_order ASC, create_time DESC
</select>
<!-- 根据分类查询 -->
<select id="selectTaskMetaByCategory" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM tb_crontab_task_meta
WHERE category = #{category}
AND deleted = 0
ORDER BY sort_order ASC
</select>
<!-- 分页查询 -->
<select id="selectTaskMetaPage" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM tb_crontab_task_meta
<include refid="Base_Where_Clause" />
ORDER BY sort_order ASC, create_time DESC
LIMIT #{pageParam.offset}, #{pageParam.pageSize}
</select>
<!-- 查询总数 -->
<select id="countSelectTaskMeta" resultType="int">
SELECT COUNT(*)
FROM tb_crontab_task_meta
<include refid="Base_Where_Clause" />
</select>
</mapper>