From 89ccf9d5554664a5bcf662bd546d9acc743ff172 Mon Sep 17 00:00:00 2001 From: dengqichen Date: Fri, 30 May 2025 11:20:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=8E=AF=E5=A2=83=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E9=85=8D=E7=BD=AE=EF=BC=8C=E5=8E=BB=E9=99=A4=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E6=97=A0=E7=94=A8=E5=BC=80=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 -- .../reminder/config/TaskReminderConfig.java | 21 ++++- .../controller/TaskReminderController.java | 13 ++-- .../reminder/service/EnabledCheckService.java | 44 ++++------- .../reminder/service/TaskReminderService.java | 4 +- .../service/WechatWebhookService.java | 62 +++++++-------- .../reminder/strategy/EnabledChecker.java | 30 -------- .../strategy/ScheduleEnabledChecker.java | 42 ---------- ...{application.yml => application-local.yml} | 12 +-- src/main/resources/application-prod.yml | 77 +++++++++++++++++++ 10 files changed, 156 insertions(+), 154 deletions(-) delete mode 100644 src/main/java/com/zeodao/reminder/strategy/EnabledChecker.java delete mode 100644 src/main/java/com/zeodao/reminder/strategy/ScheduleEnabledChecker.java rename src/main/resources/{application.yml => application-local.yml} (91%) create mode 100644 src/main/resources/application-prod.yml diff --git a/.gitignore b/.gitignore index 8c07e1f..b5167cb 100644 --- a/.gitignore +++ b/.gitignore @@ -54,11 +54,6 @@ buildNumber.properties ehthumbs.db Thumbs.db -# Spring Boot -application-local.yml -application-dev.yml -application-prod.yml - # Temporary files *.tmp *.temp diff --git a/src/main/java/com/zeodao/reminder/config/TaskReminderConfig.java b/src/main/java/com/zeodao/reminder/config/TaskReminderConfig.java index aa6ca90..a6c8e00 100644 --- a/src/main/java/com/zeodao/reminder/config/TaskReminderConfig.java +++ b/src/main/java/com/zeodao/reminder/config/TaskReminderConfig.java @@ -1,5 +1,6 @@ package com.zeodao.reminder.config; +import com.zeodao.reminder.enums.TaskSystemType; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @@ -65,7 +66,7 @@ public class TaskReminderConfig { private String id; private String name; private Webhook webhook = new Webhook(); - private String taskSystem; + private TaskSystemType taskSystem; private Map schedules = new HashMap<>(); private Zentao zentao = new Zentao(); @@ -95,14 +96,28 @@ public class TaskReminderConfig { this.webhook = webhook; } - public String getTaskSystem() { + public TaskSystemType getTaskSystem() { return taskSystem; } - public void setTaskSystem(String taskSystem) { + public void setTaskSystem(TaskSystemType taskSystem) { this.taskSystem = taskSystem; } + /** + * 设置任务系统类型(字符串版本,用于配置文件兼容) + */ + public void setTaskSystem(String taskSystemCode) { + this.taskSystem = TaskSystemType.fromCode(taskSystemCode); + } + + /** + * 获取任务系统代码(字符串版本,用于向后兼容) + */ + public String getTaskSystemCode() { + return taskSystem != null ? taskSystem.getCode() : null; + } + public Map getSchedules() { return schedules; } diff --git a/src/main/java/com/zeodao/reminder/controller/TaskReminderController.java b/src/main/java/com/zeodao/reminder/controller/TaskReminderController.java index c24cbfe..f9432b9 100644 --- a/src/main/java/com/zeodao/reminder/controller/TaskReminderController.java +++ b/src/main/java/com/zeodao/reminder/controller/TaskReminderController.java @@ -1,6 +1,7 @@ package com.zeodao.reminder.controller; import com.zeodao.reminder.config.TaskReminderConfig; +import com.zeodao.reminder.enums.TaskSystemType; import com.zeodao.reminder.model.ZentaoTask; import com.zeodao.reminder.model.ZentaoBug; import com.zeodao.reminder.scheduler.DynamicTaskScheduler; @@ -239,7 +240,7 @@ public class TaskReminderController { return ResponseEntity.ok(response); } - if (!"zentao".equals(group.getTaskSystem())) { + if (group.getTaskSystem() != TaskSystemType.ZENTAO) { response.put("success", false); response.put("message", "该群组不是禅道类型"); return ResponseEntity.ok(response); @@ -274,7 +275,7 @@ public class TaskReminderController { return ResponseEntity.ok(response); } - if (!"zentao".equals(group.getTaskSystem())) { + if (group.getTaskSystem() != TaskSystemType.ZENTAO) { response.put("success", false); response.put("message", "该群组不是禅道类型"); return ResponseEntity.ok(response); @@ -307,7 +308,7 @@ public class TaskReminderController { return ResponseEntity.ok(response); } - if (!"zentao".equals(group.getTaskSystem())) { + if (group.getTaskSystem() != TaskSystemType.ZENTAO) { response.put("success", false); response.put("message", "该群组不是禅道类型"); return ResponseEntity.ok(response); @@ -342,7 +343,7 @@ public class TaskReminderController { return ResponseEntity.ok(response); } - if (!"zentao".equals(group.getTaskSystem())) { + if (group.getTaskSystem() != TaskSystemType.ZENTAO) { response.put("success", false); response.put("message", "该群组不是禅道类型"); return ResponseEntity.ok(response); @@ -375,7 +376,7 @@ public class TaskReminderController { return ResponseEntity.ok(response); } - if (!"zentao".equals(group.getTaskSystem())) { + if (group.getTaskSystem() != TaskSystemType.ZENTAO) { response.put("success", false); response.put("message", "该群组不是禅道类型"); return ResponseEntity.ok(response); @@ -414,7 +415,7 @@ public class TaskReminderController { return ResponseEntity.ok(response); } - if (!"zentao".equals(group.getTaskSystem())) { + if (group.getTaskSystem() != TaskSystemType.ZENTAO) { response.put("success", false); response.put("message", "该群组不是禅道类型"); return ResponseEntity.ok(response); diff --git a/src/main/java/com/zeodao/reminder/service/EnabledCheckService.java b/src/main/java/com/zeodao/reminder/service/EnabledCheckService.java index f6e6f8a..435caaf 100644 --- a/src/main/java/com/zeodao/reminder/service/EnabledCheckService.java +++ b/src/main/java/com/zeodao/reminder/service/EnabledCheckService.java @@ -2,18 +2,13 @@ package com.zeodao.reminder.service; import com.zeodao.reminder.config.TaskReminderConfig; import com.zeodao.reminder.enums.ScheduleType; -import com.zeodao.reminder.strategy.EnabledChecker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.Comparator; -import java.util.List; - /** * 启用状态检查服务 - * 使用责任链模式按优先级检查各级启用状态 + * 简化版本:直接检查提醒类型的启用状态 * * @author Zeodao * @version 2.0.0 @@ -23,38 +18,29 @@ public class EnabledCheckService { private static final Logger logger = LoggerFactory.getLogger(EnabledCheckService.class); - private final List enabledCheckers; - - @Autowired - public EnabledCheckService(List enabledCheckers) { - // 按优先级排序 - this.enabledCheckers = enabledCheckers.stream() - .sorted(Comparator.comparingInt(EnabledChecker::getPriority)) - .toList(); - - logger.info("初始化启用状态检查器,共 {} 个检查器", this.enabledCheckers.size()); - } - /** * 检查群组的特定提醒类型是否启用 - * 使用责任链模式,任何一个检查器返回false则整体返回false * * @param group 群组配置 * @param scheduleType 提醒类型 * @return 是否启用 */ public boolean isReminderEnabled(TaskReminderConfig.Group group, ScheduleType scheduleType) { - for (EnabledChecker checker : enabledCheckers) { - if (!checker.isEnabled(group, scheduleType)) { - logger.debug("检查器 {} 返回false,群组: {}, 提醒类型: {}", - checker.getClass().getSimpleName(), group.getName(), scheduleType.getDescription()); - return false; - } + TaskReminderConfig.Schedule schedule = group.getSchedules().get(scheduleType.getCode()); + + if (schedule == null) { + logger.debug("群组 {} 未配置 {} 提醒", group.getName(), scheduleType.getDescription()); + return false; } - - logger.debug("所有检查器通过,群组: {}, 提醒类型: {} 已启用", - group.getName(), scheduleType.getDescription()); - return true; + + boolean enabled = schedule.isEnabled(); + if (!enabled) { + logger.debug("群组 {} 的 {} 提醒已禁用", group.getName(), scheduleType.getDescription()); + } else { + logger.debug("群组 {} 的 {} 提醒已启用", group.getName(), scheduleType.getDescription()); + } + + return enabled; } /** diff --git a/src/main/java/com/zeodao/reminder/service/TaskReminderService.java b/src/main/java/com/zeodao/reminder/service/TaskReminderService.java index b31d525..bb7f1b4 100644 --- a/src/main/java/com/zeodao/reminder/service/TaskReminderService.java +++ b/src/main/java/com/zeodao/reminder/service/TaskReminderService.java @@ -72,7 +72,7 @@ public class TaskReminderService { // 转换字符串类型为枚举类型 ScheduleType scheduleTypeEnum = ScheduleType.fromCode(scheduleType); - TaskSystemType taskSystemTypeEnum = TaskSystemType.fromCode(group.getTaskSystem()); + TaskSystemType taskSystemTypeEnum = group.getTaskSystem(); if (scheduleTypeEnum == null) { logger.error("无效的提醒类型: {}", scheduleType); @@ -80,7 +80,7 @@ public class TaskReminderService { } if (taskSystemTypeEnum == null) { - logger.error("无效的任务系统类型: {}", group.getTaskSystem()); + logger.error("无效的任务系统类型: {}", group.getTaskSystemCode()); return; } diff --git a/src/main/java/com/zeodao/reminder/service/WechatWebhookService.java b/src/main/java/com/zeodao/reminder/service/WechatWebhookService.java index 2ddf020..a71abd2 100644 --- a/src/main/java/com/zeodao/reminder/service/WechatWebhookService.java +++ b/src/main/java/com/zeodao/reminder/service/WechatWebhookService.java @@ -2,6 +2,7 @@ package com.zeodao.reminder.service; import com.fasterxml.jackson.databind.ObjectMapper; import com.zeodao.reminder.config.TaskReminderConfig; +import com.zeodao.reminder.enums.TaskSystemType; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; @@ -233,14 +234,15 @@ public class WechatWebhookService { StringBuilder message = new StringBuilder(); // 根据任务管理系统类型生成不同的标题和操作指引 - String systemName = getTaskSystemDisplayName(group.getTaskSystem()); - String systemIcon = getTaskSystemIcon(group.getTaskSystem()); + TaskSystemType taskSystemType = group.getTaskSystem(); + String systemName = taskSystemType != null ? taskSystemType.getDescription() : "任务管理系统"; + String systemIcon = getTaskSystemIcon(taskSystemType); message.append("## ").append(systemIcon).append(" ").append(systemName).append("任务状态提醒\n\n"); message.append("⏰ **时间:** ").append(timestamp).append(" (").append(dayOfWeek).append(")\n\n"); message.append("📢 ").append(baseMessage).append("\n\n"); message.append("🔗 **操作指引:**\n"); - message.append(getTaskSystemInstructions(group.getTaskSystem())); + message.append(getTaskSystemInstructions(taskSystemType)); message.append("💡 及时更新任务状态有助于团队协作和项目管理"); return message.toString(); @@ -258,32 +260,23 @@ public class WechatWebhookService { return createTaskReminderMessage(allGroups.get(0).getId(), baseMessage, timeType); } - /** - * 获取任务管理系统的显示名称 - */ - private String getTaskSystemDisplayName(String taskSystem) { - switch (taskSystem.toLowerCase()) { - case "zentao": return "禅道"; - case "smartsheet": return "智能表格"; - case "jira": return "Jira"; - case "trello": return "Trello"; - case "asana": return "Asana"; - case "notion": return "Notion"; - default: return "任务管理系统"; - } - } + /** * 获取任务管理系统的图标 */ - private String getTaskSystemIcon(String taskSystem) { - switch (taskSystem.toLowerCase()) { - case "zentao": return "📋"; - case "smartsheet": return "📊"; - case "jira": return "🎯"; - case "trello": return "📌"; - case "asana": return "✅"; - case "notion": return "📝"; + private String getTaskSystemIcon(TaskSystemType taskSystemType) { + if (taskSystemType == null) { + return "📋"; + } + + switch (taskSystemType) { + case ZENTAO: return "📋"; + case SMARTSHEET: return "📊"; + case JIRA: return "🎯"; + case TRELLO: return "📌"; + case ASANA: return "✅"; + case NOTION: return "📝"; default: return "📋"; } } @@ -291,24 +284,31 @@ public class WechatWebhookService { /** * 获取任务管理系统的操作指引 */ - private String getTaskSystemInstructions(String taskSystem) { - switch (taskSystem.toLowerCase()) { - case "zentao": + private String getTaskSystemInstructions(TaskSystemType taskSystemType) { + if (taskSystemType == null) { + return "1. 登录任务管理系统\n" + + "2. 查看分配给自己的任务\n" + + "3. 更新任务状态和进度\n" + + "4. 添加必要的工作记录\n\n"; + } + + switch (taskSystemType) { + case ZENTAO: return "1. 登录禅道系统\n" + "2. 查看分配给自己的任务\n" + "3. 更新任务状态和进度\n" + "4. 添加必要的工作日志\n\n"; - case "smartsheet": + case SMARTSHEET: return "1. 打开智能表格\n" + "2. 找到自己负责的任务行\n" + "3. 更新任务状态和完成百分比\n" + "4. 添加备注说明进展情况\n\n"; - case "jira": + case JIRA: return "1. 登录Jira系统\n" + "2. 查看分配给自己的Issue\n" + "3. 更新Issue状态\n" + "4. 记录工作日志和时间\n\n"; - case "trello": + case TRELLO: return "1. 打开Trello看板\n" + "2. 找到自己的任务卡片\n" + "3. 移动卡片到对应状态列\n" + diff --git a/src/main/java/com/zeodao/reminder/strategy/EnabledChecker.java b/src/main/java/com/zeodao/reminder/strategy/EnabledChecker.java deleted file mode 100644 index faee316..0000000 --- a/src/main/java/com/zeodao/reminder/strategy/EnabledChecker.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.zeodao.reminder.strategy; - -import com.zeodao.reminder.config.TaskReminderConfig; -import com.zeodao.reminder.enums.ScheduleType; - -/** - * 启用状态检查器接口 - * 使用策略模式检查不同级别的启用状态 - * - * @author Zeodao - * @version 2.0.0 - */ -public interface EnabledChecker { - - /** - * 检查是否启用 - * - * @param group 群组配置 - * @param scheduleType 提醒类型 - * @return 是否启用 - */ - boolean isEnabled(TaskReminderConfig.Group group, ScheduleType scheduleType); - - /** - * 获取检查器的优先级(数字越小优先级越高) - * - * @return 优先级 - */ - int getPriority(); -} diff --git a/src/main/java/com/zeodao/reminder/strategy/ScheduleEnabledChecker.java b/src/main/java/com/zeodao/reminder/strategy/ScheduleEnabledChecker.java deleted file mode 100644 index 9d4531d..0000000 --- a/src/main/java/com/zeodao/reminder/strategy/ScheduleEnabledChecker.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.zeodao.reminder.strategy; - -import com.zeodao.reminder.config.TaskReminderConfig; -import com.zeodao.reminder.enums.ScheduleType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -/** - * 提醒计划级别启用状态检查器 - * 检查特定提醒类型是否启用 - * - * @author Zeodao - * @version 2.0.0 - */ -@Component -public class ScheduleEnabledChecker implements EnabledChecker { - - private static final Logger logger = LoggerFactory.getLogger(ScheduleEnabledChecker.class); - - @Override - public boolean isEnabled(TaskReminderConfig.Group group, ScheduleType scheduleType) { - TaskReminderConfig.Schedule schedule = group.getSchedules().get(scheduleType.getCode()); - - if (schedule == null) { - logger.debug("群组 {} 未配置 {} 提醒", group.getName(), scheduleType.getDescription()); - return false; - } - - boolean enabled = schedule.isEnabled(); - if (!enabled) { - logger.debug("群组 {} 的 {} 提醒已禁用", group.getName(), scheduleType.getDescription()); - } - - return enabled; - } - - @Override - public int getPriority() { - return 2; // 次优先级,在群组启用的前提下检查具体提醒类型 - } -} diff --git a/src/main/resources/application.yml b/src/main/resources/application-local.yml similarity index 91% rename from src/main/resources/application.yml rename to src/main/resources/application-local.yml index 87c423a..1e40be2 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application-local.yml @@ -15,8 +15,8 @@ task: # 群组配置列表 groups: # 禅道团队群 - - id: "zentao-team" - name: "禅道开发团队" + - id: "chainhub" + name: "一站式平台" webhook: url: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=614b110b-8957-4be8-95b9-4eca84c15028" task-system: "zentao" # 任务管理系统类型:zentao, smartsheet, jira, trello 等 @@ -45,11 +45,11 @@ task: overdue-reminder: time: "0 0 10 * * MON-FRI" # 工作日上午10点 message: "禅道逾期任务提醒" # 这个消息会被系统动态生成,包含具体的任务和BUG统计信息 - enabled: false # 启用逾期提醒 + enabled: true # 启用逾期提醒 # 智能表格团队群 - - id: "smartsheet-team" - name: "智能表格团队" + - id: "longi-scp" + name: "隆基需求计划" webhook: url: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=614b110b-8957-4be8-95b9-4eca84c15028" task-system: "smartsheet" @@ -61,7 +61,7 @@ task: evening: time: "0 20 17 * * MON-FRI" # 工作日下午5点20分 message: "下班前提醒:请在智能表格中更新今日工作完成情况,为明天做好准备!" - enabled: false # 禁用晚上提醒(示例:智能表格团队不需要晚上提醒) + enabled: true # 禁用晚上提醒(示例:智能表格团队不需要晚上提醒) # 日志配置 logging: diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml new file mode 100644 index 0000000..0d37345 --- /dev/null +++ b/src/main/resources/application-prod.yml @@ -0,0 +1,77 @@ +server: + port: 8080 + +spring: + application: + name: zeodao-task-reminder + +# 多群任务提醒配置 +task: + reminder: + # 全局默认配置 + global: + timeout: 5000 # 超时时间(毫秒) + + # 群组配置列表 + groups: + # 禅道团队群 + - id: "chainhub" + name: "一站式平台" + webhook: + url: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=614b110b-8957-4be8-95b9-4eca84c15028" + task-system: "zentao" # 任务管理系统类型:zentao, smartsheet, jira, trello 等 + # 禅道配置 + zentao: + api-url: "https://zentao.iscmtech.com" + username: "admin" # 请替换为实际的禅道用户名 + password: "Lianyu!@#~123456" # 请替换为实际的禅道密码 + project-id: 38 # 项目ID(同时用于获取任务和BUG) + kanban-id: 39 # 看板ID(看板模式项目需要) + # 用户映射:禅道用户名 -> 企业微信手机号(显示使用真实姓名) + user-mapping: + "dengqichen": "18525522818" + "songwei": "15724574541" + # 也可以直接用用户名映射 + # "zhangsan": "13600136000" + schedules: + morning: + time: "0 0 9 * * MON-FRI" # 工作日早上9点 + message: "早上好!新的一天开始了,请大家及时登录禅道系统刷新今日的任务状态,确保任务进度准确反映当前工作情况。" + enabled: true # 启用早上提醒 + evening: + time: "0 30 17 * * MON-FRI" # 工作日下午5:30 + message: "下班前提醒:请大家登录禅道系统,及时更新今日任务的完成状态和进度,为明天的工作安排做好准备!" + enabled: true # 启用晚上提醒 + overdue-reminder: + time: "0 0 10 * * MON-FRI" # 工作日上午10点 + message: "禅道逾期任务提醒" # 这个消息会被系统动态生成,包含具体的任务和BUG统计信息 + enabled: true # 启用逾期提醒 + + # 智能表格团队群 + - id: "longi-scp" + name: "隆基需求计划" + webhook: + url: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=ed54908b-0f58-46b7-beb6-8facca4438d6" + task-system: "smartsheet" + schedules: + morning: + time: "0 50 8 * * MON-FRI" # 工作日早上8点50分 + message: "早上好!请大家及时更新智能表格中的任务状态,确保项目进度信息准确无误。" + enabled: true # 启用早上提醒 + evening: + time: "0 20 17 * * MON-FRI" # 工作日下午5点20分 + message: "下班前提醒:请在智能表格中更新今日工作完成情况,为明天做好准备!" + enabled: true # 禁用晚上提醒(示例:智能表格团队不需要晚上提醒) + +# 日志配置 +logging: + level: + com.zeodao.reminder: DEBUG + org.springframework.web: INFO + pattern: + console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" + file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" + file: + name: logs/task-reminder.log + max-size: 10MB + max-history: 30