每个提醒的类型都增加了枚举

This commit is contained in:
dengqichen 2025-05-29 17:55:48 +08:00
parent 55d8ad26c0
commit b3d98ce025
11 changed files with 466 additions and 14 deletions

View File

@ -157,6 +157,7 @@ public class TaskReminderConfig {
public static class Schedule { public static class Schedule {
private String time; private String time;
private String type = "text"; // 默认为文本类型
private String message; private String message;
public String getTime() { public String getTime() {
@ -167,6 +168,14 @@ public class TaskReminderConfig {
this.time = time; this.time = time;
} }
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getMessage() { public String getMessage() {
return message; return message;
} }

View File

@ -161,6 +161,26 @@ public class TaskReminderController {
return ResponseEntity.ok(response); return ResponseEntity.ok(response);
} }
/**
* 手动触发逾期任务提醒
*/
@PostMapping("/overdue-reminder")
public ResponseEntity<Map<String, Object>> triggerOverdueReminder() {
Map<String, Object> response = new HashMap<>();
try {
taskReminderService.sendAllOverdueReminders();
response.put("success", true);
response.put("message", "所有群组逾期任务提醒已触发");
} catch (Exception e) {
logger.error("触发逾期任务提醒失败", e);
response.put("success", false);
response.put("message", "触发逾期任务提醒失败:" + e.getMessage());
}
return ResponseEntity.ok(response);
}
/** /**
* 手动触发指定群组的提醒 * 手动触发指定群组的提醒
*/ */

View File

@ -0,0 +1,67 @@
package com.zeodao.reminder.enums;
/**
* 提醒类型枚举
*
* @author Zeodao
* @version 2.0.0
*/
public enum ScheduleType {
/**
* 早上提醒
*/
MORNING("morning", "早上提醒"),
/**
* 晚上提醒
*/
EVENING("evening", "晚上提醒"),
/**
* 逾期任务提醒
*/
OVERDUE_REMINDER("overdue-reminder", "逾期任务提醒");
private final String code;
private final String description;
ScheduleType(String code, String description) {
this.code = code;
this.description = description;
}
public String getCode() {
return code;
}
public String getDescription() {
return description;
}
/**
* 根据代码获取枚举
*/
public static ScheduleType fromCode(String code) {
for (ScheduleType type : values()) {
if (type.code.equals(code)) {
return type;
}
}
return null;
}
/**
* 判断是否为文本提醒类型
*/
public boolean isTextReminder() {
return this == MORNING || this == EVENING;
}
/**
* 判断是否为逾期提醒类型
*/
public boolean isOverdueReminder() {
return this == OVERDUE_REMINDER;
}
}

View File

@ -0,0 +1,68 @@
package com.zeodao.reminder.enums;
/**
* 任务系统类型枚举
*
* @author Zeodao
* @version 2.0.0
*/
public enum TaskSystemType {
/**
* 禅道
*/
ZENTAO("zentao", "禅道"),
/**
* 智能表格
*/
SMARTSHEET("smartsheet", "智能表格"),
/**
* Jira
*/
JIRA("jira", "Jira"),
/**
* Trello
*/
TRELLO("trello", "Trello"),
/**
* Asana
*/
ASANA("asana", "Asana"),
/**
* Notion
*/
NOTION("notion", "Notion");
private final String code;
private final String description;
TaskSystemType(String code, String description) {
this.code = code;
this.description = description;
}
public String getCode() {
return code;
}
public String getDescription() {
return description;
}
/**
* 根据代码获取枚举
*/
public static TaskSystemType fromCode(String code) {
for (TaskSystemType type : values()) {
if (type.code.equals(code)) {
return type;
}
}
return null;
}
}

View File

@ -1,6 +1,10 @@
package com.zeodao.reminder.service; package com.zeodao.reminder.service;
import com.zeodao.reminder.config.TaskReminderConfig; import com.zeodao.reminder.config.TaskReminderConfig;
import com.zeodao.reminder.enums.ScheduleType;
import com.zeodao.reminder.enums.TaskSystemType;
import com.zeodao.reminder.strategy.ReminderHandler;
import com.zeodao.reminder.strategy.ReminderHandlerFactory;
import com.zeodao.reminder.util.HolidayUtil; import com.zeodao.reminder.util.HolidayUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -32,7 +36,7 @@ public class TaskReminderService {
private TaskReminderConfig taskReminderConfig; private TaskReminderConfig taskReminderConfig;
@Autowired @Autowired
private ZentaoTaskReminderService zentaoTaskReminderService; private ReminderHandlerFactory reminderHandlerFactory;
/** /**
* 发送指定群组和时间段的任务提醒 * 发送指定群组和时间段的任务提醒
@ -62,20 +66,27 @@ public class TaskReminderService {
logger.info("开始发送任务提醒 - 群组: {}, 类型: {}", group.getName(), scheduleType); logger.info("开始发送任务提醒 - 群组: {}, 类型: {}", group.getName(), scheduleType);
// 根据任务系统类型选择不同的提醒方式 // 转换字符串类型为枚举类型
if ("zentao".equals(group.getTaskSystem())) { ScheduleType scheduleTypeEnum = ScheduleType.fromCode(scheduleType);
// 发送禅道任务提醒 TaskSystemType taskSystemTypeEnum = TaskSystemType.fromCode(group.getTaskSystem());
zentaoTaskReminderService.sendTaskReminder(group);
} else {
// 发送传统的文本提醒
String message = wechatWebhookService.createTaskReminderMessage(groupId, schedule.getMessage(), scheduleType + "提醒");
boolean success = wechatWebhookService.sendMarkdownMessage(groupId, message);
if (success) { if (scheduleTypeEnum == null) {
logger.info("任务提醒发送成功 - 群组: {}, 类型: {}", group.getName(), scheduleType); logger.error("无效的提醒类型: {}", scheduleType);
} else { return;
logger.error("任务提醒发送失败 - 群组: {}, 类型: {}", group.getName(), scheduleType); }
}
if (taskSystemTypeEnum == null) {
logger.error("无效的任务系统类型: {}", group.getTaskSystem());
return;
}
// 使用策略模式选择合适的处理器
ReminderHandler handler = reminderHandlerFactory.getHandler(scheduleTypeEnum, taskSystemTypeEnum);
if (handler != null) {
handler.handleReminder(group, scheduleTypeEnum, schedule);
} else {
logger.error("未找到合适的提醒处理器 - 群组: {}, 类型: {}, 任务系统: {}",
group.getName(), scheduleTypeEnum.getDescription(), taskSystemTypeEnum.getDescription());
} }
} }
@ -103,6 +114,18 @@ public class TaskReminderService {
} }
} }
/**
* 发送所有启用群组的逾期任务提醒
*/
public void sendAllOverdueReminders() {
List<TaskReminderConfig.Group> enabledGroups = taskReminderConfig.getEnabledGroups();
for (TaskReminderConfig.Group group : enabledGroups) {
if (group.getSchedules().containsKey("overdue-reminder")) {
sendReminder(group.getId(), "overdue-reminder");
}
}
}
/** /**
* 兼容旧版本的方法 * 兼容旧版本的方法
*/ */

View File

@ -0,0 +1,33 @@
package com.zeodao.reminder.strategy;
import com.zeodao.reminder.config.TaskReminderConfig;
import com.zeodao.reminder.enums.ScheduleType;
import com.zeodao.reminder.enums.TaskSystemType;
/**
* 提醒处理器接口
* 使用策略模式处理不同类型的提醒
*
* @author Zeodao
* @version 2.0.0
*/
public interface ReminderHandler {
/**
* 判断是否支持处理指定的提醒类型
*
* @param scheduleType 提醒类型
* @param taskSystemType 任务系统类型
* @return 是否支持
*/
boolean supports(ScheduleType scheduleType, TaskSystemType taskSystemType);
/**
* 处理提醒
*
* @param group 群组配置
* @param scheduleType 提醒类型
* @param schedule 提醒配置
*/
void handleReminder(TaskReminderConfig.Group group, ScheduleType scheduleType, TaskReminderConfig.Schedule schedule);
}

View File

@ -0,0 +1,66 @@
package com.zeodao.reminder.strategy;
import com.zeodao.reminder.enums.ScheduleType;
import com.zeodao.reminder.enums.TaskSystemType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 提醒处理器工厂
* 根据提醒类型和任务系统选择合适的处理器
*
* @author Zeodao
* @version 2.0.0
*/
@Component
public class ReminderHandlerFactory {
private static final Logger logger = LoggerFactory.getLogger(ReminderHandlerFactory.class);
@Autowired
private List<ReminderHandler> reminderHandlers;
/**
* 获取合适的提醒处理器
*
* @param scheduleType 提醒类型
* @param taskSystemType 任务系统类型
* @return 提醒处理器如果没有找到则返回null
*/
public ReminderHandler getHandler(ScheduleType scheduleType, TaskSystemType taskSystemType) {
for (ReminderHandler handler : reminderHandlers) {
if (handler.supports(scheduleType, taskSystemType)) {
logger.debug("找到处理器: {} 用于处理 scheduleType={}, taskSystemType={}",
handler.getClass().getSimpleName(), scheduleType.getDescription(), taskSystemType.getDescription());
return handler;
}
}
logger.warn("未找到合适的处理器 - scheduleType: {}, taskSystemType: {}",
scheduleType.getDescription(), taskSystemType.getDescription());
return null;
}
/**
* 获取合适的提醒处理器字符串参数版本用于兼容
*
* @param scheduleTypeCode 提醒类型代码
* @param taskSystemCode 任务系统类型代码
* @return 提醒处理器如果没有找到则返回null
*/
public ReminderHandler getHandler(String scheduleTypeCode, String taskSystemCode) {
ScheduleType scheduleType = ScheduleType.fromCode(scheduleTypeCode);
TaskSystemType taskSystemType = TaskSystemType.fromCode(taskSystemCode);
if (scheduleType == null || taskSystemType == null) {
logger.warn("无效的类型代码 - scheduleTypeCode: {}, taskSystemCode: {}", scheduleTypeCode, taskSystemCode);
return null;
}
return getHandler(scheduleType, taskSystemType);
}
}

View File

@ -0,0 +1,53 @@
package com.zeodao.reminder.strategy;
import com.zeodao.reminder.config.TaskReminderConfig;
import com.zeodao.reminder.enums.ScheduleType;
import com.zeodao.reminder.enums.TaskSystemType;
import com.zeodao.reminder.service.WechatWebhookService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 文本提醒处理器
* 处理 morning evening 类型的文本提醒
*
* @author Zeodao
* @version 2.0.0
*/
@Component
public class TextReminderHandler implements ReminderHandler {
private static final Logger logger = LoggerFactory.getLogger(TextReminderHandler.class);
@Autowired
private WechatWebhookService wechatWebhookService;
@Override
public boolean supports(ScheduleType scheduleType, TaskSystemType taskSystemType) {
// 支持所有任务系统的文本提醒类型
return scheduleType.isTextReminder();
}
@Override
public void handleReminder(TaskReminderConfig.Group group, ScheduleType scheduleType, TaskReminderConfig.Schedule schedule) {
logger.info("处理文本提醒 - 群组: {}, 类型: {}", group.getName(), scheduleType.getDescription());
// 生成带格式的提醒消息
String message = wechatWebhookService.createTaskReminderMessage(
group.getId(),
schedule.getMessage(),
scheduleType.getDescription()
);
// 发送消息
boolean success = wechatWebhookService.sendMarkdownMessage(group.getId(), message);
if (success) {
logger.info("文本提醒发送成功 - 群组: {}, 类型: {}", group.getName(), scheduleType.getDescription());
} else {
logger.error("文本提醒发送失败 - 群组: {}, 类型: {}", group.getName(), scheduleType.getDescription());
}
}
}

View File

@ -0,0 +1,45 @@
package com.zeodao.reminder.strategy;
import com.zeodao.reminder.config.TaskReminderConfig;
import com.zeodao.reminder.enums.ScheduleType;
import com.zeodao.reminder.enums.TaskSystemType;
import com.zeodao.reminder.service.ZentaoTaskReminderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 禅道逾期任务提醒处理器
* 处理禅道系统的 overdue-reminder 类型提醒
*
* @author Zeodao
* @version 2.0.0
*/
@Component
public class ZentaoOverdueReminderHandler implements ReminderHandler {
private static final Logger logger = LoggerFactory.getLogger(ZentaoOverdueReminderHandler.class);
@Autowired
private ZentaoTaskReminderService zentaoTaskReminderService;
@Override
public boolean supports(ScheduleType scheduleType, TaskSystemType taskSystemType) {
// 只支持禅道系统的逾期提醒
return scheduleType.isOverdueReminder() && taskSystemType == TaskSystemType.ZENTAO;
}
@Override
public void handleReminder(TaskReminderConfig.Group group, ScheduleType scheduleType, TaskReminderConfig.Schedule schedule) {
logger.info("处理禅道逾期任务提醒 - 群组: {}", group.getName());
try {
// 发送禅道任务状态统计提醒包含任务和BUG详情
zentaoTaskReminderService.sendTaskReminder(group);
logger.info("禅道逾期任务提醒发送成功 - 群组: {}", group.getName());
} catch (Exception e) {
logger.error("禅道逾期任务提醒发送失败 - 群组: {}", group.getName(), e);
}
}
}

View File

@ -40,6 +40,9 @@ task:
evening: evening:
time: "0 30 17 * * MON-FRI" # 工作日下午5:30 time: "0 30 17 * * MON-FRI" # 工作日下午5:30
message: "下班前提醒:请大家登录禅道系统,及时更新今日任务的完成状态和进度,为明天的工作安排做好准备!" message: "下班前提醒:请大家登录禅道系统,及时更新今日任务的完成状态和进度,为明天的工作安排做好准备!"
overdue-reminder:
time: "0 0 10 * * MON-FRI" # 工作日上午10点
message: "禅道逾期任务提醒" # 这个消息会被系统动态生成包含具体的任务和BUG统计信息
enabled: true enabled: true
# 智能表格团队群 # 智能表格团队群

View File

@ -0,0 +1,65 @@
package com.zeodao.reminder.strategy;
import com.zeodao.reminder.enums.ScheduleType;
import com.zeodao.reminder.enums.TaskSystemType;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.*;
/**
* 提醒处理器工厂测试
*
* @author Zeodao
* @version 2.0.0
*/
@SpringBootTest
public class ReminderHandlerFactoryTest {
@Autowired
private ReminderHandlerFactory reminderHandlerFactory;
@Test
public void testGetTextReminderHandler() {
// 测试文本提醒处理器
ReminderHandler handler = reminderHandlerFactory.getHandler(ScheduleType.MORNING, TaskSystemType.ZENTAO);
assertNotNull(handler);
assertTrue(handler instanceof TextReminderHandler);
handler = reminderHandlerFactory.getHandler(ScheduleType.EVENING, TaskSystemType.SMARTSHEET);
assertNotNull(handler);
assertTrue(handler instanceof TextReminderHandler);
}
@Test
public void testGetZentaoOverdueReminderHandler() {
// 测试禅道逾期提醒处理器
ReminderHandler handler = reminderHandlerFactory.getHandler(ScheduleType.OVERDUE_REMINDER, TaskSystemType.ZENTAO);
assertNotNull(handler);
assertTrue(handler instanceof ZentaoOverdueReminderHandler);
}
@Test
public void testUnsupportedCombination() {
// 测试不支持的组合
ReminderHandler handler = reminderHandlerFactory.getHandler(ScheduleType.OVERDUE_REMINDER, TaskSystemType.SMARTSHEET);
assertNull(handler);
}
@Test
public void testStringParameterVersion() {
// 测试字符串参数版本
ReminderHandler handler = reminderHandlerFactory.getHandler("morning", "zentao");
assertNotNull(handler);
assertTrue(handler instanceof TextReminderHandler);
handler = reminderHandlerFactory.getHandler("overdue-reminder", "zentao");
assertNotNull(handler);
assertTrue(handler instanceof ZentaoOverdueReminderHandler);
// 测试无效代码
handler = reminderHandlerFactory.getHandler("unknown-type", "zentao");
assertNull(handler);
}
}