格式化
This commit is contained in:
parent
c5233719cb
commit
65e9dc7b16
@ -7,7 +7,7 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
|
||||
/**
|
||||
* 任务调度器配置
|
||||
*
|
||||
*
|
||||
* @author Zeodao
|
||||
* @version 2.0.0
|
||||
*/
|
||||
|
||||
@ -20,6 +20,7 @@ import java.util.Map;
|
||||
public class TaskReminderConfig {
|
||||
|
||||
private Global global = new Global();
|
||||
|
||||
private List<Group> groups = new ArrayList<>();
|
||||
|
||||
public Global getGlobal() {
|
||||
@ -43,13 +44,12 @@ public class TaskReminderConfig {
|
||||
*/
|
||||
public Group getGroupById(String groupId) {
|
||||
return groups.stream()
|
||||
.filter(group -> group.getId().equals(groupId))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
.filter(group -> group.getId().equals(groupId))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class Global {
|
||||
private int timeout = 5000;
|
||||
|
||||
@ -64,12 +64,17 @@ public class TaskReminderConfig {
|
||||
|
||||
public static class Group {
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
private Webhook webhook = new Webhook();
|
||||
|
||||
private TaskSystemType taskSystem;
|
||||
|
||||
private Map<String, Schedule> schedules = new HashMap<>();
|
||||
|
||||
private Zentao zentao = new Zentao();
|
||||
|
||||
private Map<String, String> userMapping = new HashMap<>();
|
||||
|
||||
public String getId() {
|
||||
@ -127,7 +132,6 @@ public class TaskReminderConfig {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Zentao getZentao() {
|
||||
return zentao;
|
||||
}
|
||||
@ -159,7 +163,9 @@ public class TaskReminderConfig {
|
||||
|
||||
public static class Schedule {
|
||||
private String time;
|
||||
|
||||
private String message;
|
||||
|
||||
private boolean enabled = true; // 默认启用
|
||||
|
||||
public String getTime() {
|
||||
@ -189,10 +195,15 @@ public class TaskReminderConfig {
|
||||
|
||||
public static class Zentao {
|
||||
private String apiUrl;
|
||||
|
||||
private String token;
|
||||
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
private Integer projectId;
|
||||
|
||||
private Integer kanbanId;
|
||||
|
||||
public String getApiUrl() {
|
||||
|
||||
@ -187,8 +187,8 @@ public class TaskReminderController {
|
||||
*/
|
||||
@PostMapping("/groups/{groupId}/{scheduleType}")
|
||||
public ResponseEntity<Map<String, Object>> triggerGroupReminder(
|
||||
@PathVariable String groupId,
|
||||
@PathVariable String scheduleType) {
|
||||
@PathVariable String groupId,
|
||||
@PathVariable String scheduleType) {
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
|
||||
try {
|
||||
|
||||
@ -7,23 +7,24 @@ package com.zeodao.reminder.enums;
|
||||
* @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) {
|
||||
|
||||
@ -7,38 +7,39 @@ package com.zeodao.reminder.enums;
|
||||
* @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) {
|
||||
|
||||
@ -16,8 +16,11 @@ import lombok.NoArgsConstructor;
|
||||
public class ProjectInfo {
|
||||
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String status;
|
||||
|
||||
private boolean exists;
|
||||
|
||||
/**
|
||||
@ -32,11 +35,16 @@ public class ProjectInfo {
|
||||
*/
|
||||
public String getStatusDescription() {
|
||||
switch (status) {
|
||||
case "wait": return "未开始";
|
||||
case "doing": return "进行中";
|
||||
case "suspended": return "已挂起";
|
||||
case "closed": return "已关闭";
|
||||
default: return "未知状态";
|
||||
case "wait":
|
||||
return "未开始";
|
||||
case "doing":
|
||||
return "进行中";
|
||||
case "suspended":
|
||||
return "已挂起";
|
||||
case "closed":
|
||||
return "已关闭";
|
||||
default:
|
||||
return "未知状态";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -13,37 +13,69 @@ import lombok.Data;
|
||||
public class ZentaoTask {
|
||||
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String type;
|
||||
|
||||
private String status;
|
||||
|
||||
private String pri;
|
||||
|
||||
private String assignedTo;
|
||||
|
||||
private String assignedToRealName;
|
||||
|
||||
private String assignedDate;
|
||||
|
||||
private String deadline;
|
||||
|
||||
private String estStarted;
|
||||
|
||||
private String realStarted;
|
||||
|
||||
private String finishedBy;
|
||||
|
||||
private String finishedDate;
|
||||
|
||||
private String canceledBy;
|
||||
|
||||
private String canceledDate;
|
||||
|
||||
private String closedBy;
|
||||
|
||||
private String closedDate;
|
||||
|
||||
private String closedReason;
|
||||
|
||||
private String lastEditedBy;
|
||||
|
||||
private String lastEditedDate;
|
||||
|
||||
private String openedBy;
|
||||
|
||||
private String openedDate;
|
||||
|
||||
private String desc;
|
||||
|
||||
private String project;
|
||||
|
||||
private String story;
|
||||
|
||||
private String storyTitle;
|
||||
|
||||
private String module;
|
||||
|
||||
private String estimate;
|
||||
|
||||
private String consumed;
|
||||
|
||||
private String left;
|
||||
|
||||
private String progress;
|
||||
|
||||
private String color;
|
||||
|
||||
private String deleted;
|
||||
|
||||
/**
|
||||
@ -150,11 +182,16 @@ public class ZentaoTask {
|
||||
*/
|
||||
public String getPriorityDesc() {
|
||||
switch (pri) {
|
||||
case "1": return "高";
|
||||
case "2": return "中";
|
||||
case "3": return "低";
|
||||
case "4": return "最低";
|
||||
default: return "普通";
|
||||
case "1":
|
||||
return "高";
|
||||
case "2":
|
||||
return "中";
|
||||
case "3":
|
||||
return "低";
|
||||
case "4":
|
||||
return "最低";
|
||||
default:
|
||||
return "普通";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,36 +14,68 @@ import lombok.Data;
|
||||
public class ZentaoUser {
|
||||
|
||||
private String id;
|
||||
|
||||
private String account;
|
||||
|
||||
private String realname;
|
||||
|
||||
private String nickname;
|
||||
|
||||
private String avatar;
|
||||
|
||||
private String birthday;
|
||||
|
||||
private String gender;
|
||||
|
||||
private String email;
|
||||
|
||||
private String skype;
|
||||
|
||||
private String qq;
|
||||
|
||||
private String yahoo;
|
||||
|
||||
private String gtalk;
|
||||
|
||||
private String wangwang;
|
||||
|
||||
private String mobile;
|
||||
|
||||
private String phone;
|
||||
|
||||
private String address;
|
||||
|
||||
private String zipcode;
|
||||
|
||||
private String join;
|
||||
|
||||
private String visits;
|
||||
|
||||
private String ip;
|
||||
|
||||
private String last;
|
||||
|
||||
private String fails;
|
||||
|
||||
private String locked;
|
||||
|
||||
private String feedback;
|
||||
|
||||
private String mail;
|
||||
|
||||
private String clientStatus;
|
||||
|
||||
private String clientLang;
|
||||
|
||||
private String dept;
|
||||
|
||||
private String role;
|
||||
|
||||
private String type;
|
||||
|
||||
private String groups;
|
||||
|
||||
private String view;
|
||||
|
||||
private String deleted;
|
||||
}
|
||||
|
||||
@ -131,8 +131,8 @@ public class DynamicTaskScheduler {
|
||||
*/
|
||||
public int getActiveTaskCount() {
|
||||
return (int) scheduledTasks.values().stream()
|
||||
.filter(future -> future != null && !future.isCancelled())
|
||||
.count();
|
||||
.filter(future -> future != null && !future.isCancelled())
|
||||
.count();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -28,7 +28,7 @@ public class UserMappingService {
|
||||
/**
|
||||
* 根据禅道用户名获取企业微信@标识
|
||||
*
|
||||
* @param group 群组配置
|
||||
* @param group 群组配置
|
||||
* @param zentaoUsername 禅道用户名
|
||||
* @return 企业微信@标识,如 @13800138000 或 null
|
||||
*/
|
||||
@ -106,7 +106,7 @@ public class UserMappingService {
|
||||
/**
|
||||
* 批量获取企业微信@标识
|
||||
*
|
||||
* @param group 群组配置
|
||||
* @param group 群组配置
|
||||
* @param zentaoUsernames 禅道用户名列表
|
||||
* @return 企业微信@标识列表
|
||||
*/
|
||||
|
||||
@ -185,10 +185,10 @@ public class WechatWebhookService {
|
||||
|
||||
// 设置请求配置
|
||||
RequestConfig requestConfig = RequestConfig.custom()
|
||||
.setConnectTimeout(timeout)
|
||||
.setSocketTimeout(timeout)
|
||||
.setConnectionRequestTimeout(timeout)
|
||||
.build();
|
||||
.setConnectTimeout(timeout)
|
||||
.setSocketTimeout(timeout)
|
||||
.setConnectionRequestTimeout(timeout)
|
||||
.build();
|
||||
httpPost.setConfig(requestConfig);
|
||||
|
||||
// 设置请求头
|
||||
@ -261,7 +261,6 @@ public class WechatWebhookService {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取任务管理系统的图标
|
||||
*/
|
||||
@ -271,13 +270,20 @@ public class WechatWebhookService {
|
||||
}
|
||||
|
||||
switch (taskSystemType) {
|
||||
case ZENTAO: return "📋";
|
||||
case SMARTSHEET: return "📊";
|
||||
case JIRA: return "🎯";
|
||||
case TRELLO: return "📌";
|
||||
case ASANA: return "✅";
|
||||
case NOTION: return "📝";
|
||||
default: return "📋";
|
||||
case ZENTAO:
|
||||
return "📋";
|
||||
case SMARTSHEET:
|
||||
return "📊";
|
||||
case JIRA:
|
||||
return "🎯";
|
||||
case TRELLO:
|
||||
return "📌";
|
||||
case ASANA:
|
||||
return "✅";
|
||||
case NOTION:
|
||||
return "📝";
|
||||
default:
|
||||
return "📋";
|
||||
}
|
||||
}
|
||||
|
||||
@ -287,37 +293,37 @@ public class WechatWebhookService {
|
||||
private String getTaskSystemInstructions(TaskSystemType taskSystemType) {
|
||||
if (taskSystemType == null) {
|
||||
return "1. 登录任务管理系统\n" +
|
||||
"2. 查看分配给自己的任务\n" +
|
||||
"3. 更新任务状态和进度\n" +
|
||||
"4. 添加必要的工作记录\n\n";
|
||||
"2. 查看分配给自己的任务\n" +
|
||||
"3. 更新任务状态和进度\n" +
|
||||
"4. 添加必要的工作记录\n\n";
|
||||
}
|
||||
|
||||
switch (taskSystemType) {
|
||||
case ZENTAO:
|
||||
return "1. 登录禅道系统\n" +
|
||||
"2. 查看分配给自己的任务\n" +
|
||||
"3. 更新任务状态和进度\n" +
|
||||
"4. 添加必要的工作日志\n\n";
|
||||
"2. 查看分配给自己的任务\n" +
|
||||
"3. 更新任务状态和进度\n" +
|
||||
"4. 添加必要的工作日志\n\n";
|
||||
case SMARTSHEET:
|
||||
return "1. 打开智能表格\n" +
|
||||
"2. 找到自己负责的任务行\n" +
|
||||
"3. 更新任务状态和完成百分比\n" +
|
||||
"4. 添加备注说明进展情况\n\n";
|
||||
"2. 找到自己负责的任务行\n" +
|
||||
"3. 更新任务状态和完成百分比\n" +
|
||||
"4. 添加备注说明进展情况\n\n";
|
||||
case JIRA:
|
||||
return "1. 登录Jira系统\n" +
|
||||
"2. 查看分配给自己的Issue\n" +
|
||||
"3. 更新Issue状态\n" +
|
||||
"4. 记录工作日志和时间\n\n";
|
||||
"2. 查看分配给自己的Issue\n" +
|
||||
"3. 更新Issue状态\n" +
|
||||
"4. 记录工作日志和时间\n\n";
|
||||
case TRELLO:
|
||||
return "1. 打开Trello看板\n" +
|
||||
"2. 找到自己的任务卡片\n" +
|
||||
"3. 移动卡片到对应状态列\n" +
|
||||
"4. 添加评论记录进展\n\n";
|
||||
"2. 找到自己的任务卡片\n" +
|
||||
"3. 移动卡片到对应状态列\n" +
|
||||
"4. 添加评论记录进展\n\n";
|
||||
default:
|
||||
return "1. 登录任务管理系统\n" +
|
||||
"2. 查看分配给自己的任务\n" +
|
||||
"3. 更新任务状态和进度\n" +
|
||||
"4. 添加必要的工作记录\n\n";
|
||||
"2. 查看分配给自己的任务\n" +
|
||||
"3. 更新任务状态和进度\n" +
|
||||
"4. 添加必要的工作记录\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,14 +332,22 @@ public class WechatWebhookService {
|
||||
*/
|
||||
private String getDayOfWeekInChinese(int dayOfWeek) {
|
||||
switch (dayOfWeek) {
|
||||
case 1: return "星期一";
|
||||
case 2: return "星期二";
|
||||
case 3: return "星期三";
|
||||
case 4: return "星期四";
|
||||
case 5: return "星期五";
|
||||
case 6: return "星期六";
|
||||
case 7: return "星期日";
|
||||
default: return "未知";
|
||||
case 1:
|
||||
return "星期一";
|
||||
case 2:
|
||||
return "星期二";
|
||||
case 3:
|
||||
return "星期三";
|
||||
case 4:
|
||||
return "星期四";
|
||||
case 5:
|
||||
return "星期五";
|
||||
case 6:
|
||||
return "星期六";
|
||||
case 7:
|
||||
return "星期日";
|
||||
default:
|
||||
return "未知";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@ public class ZentaoApiService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ZentaoApiService.class);
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private final Map<String, String> sessionCache = new HashMap<>();
|
||||
|
||||
/**
|
||||
@ -211,7 +212,8 @@ public class ZentaoApiService {
|
||||
if (rootNode.has("data")) {
|
||||
JsonNode dataNode = rootNode.get("data");
|
||||
return objectMapper.convertValue(
|
||||
dataNode, new TypeReference<List<ZentaoUser>>() {});
|
||||
dataNode, new TypeReference<List<ZentaoUser>>() {
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,10 +144,10 @@ public class ZentaoTaskReminderService {
|
||||
* 构建统一的项目状态提醒消息(包含任务和BUG)
|
||||
*/
|
||||
private String buildProjectStatusMessage(TaskReminderConfig.Group group,
|
||||
List<ZentaoTask> incompleteTasks,
|
||||
List<ZentaoBug> unresolvedBugs,
|
||||
ProjectInfo projectInfo,
|
||||
List<String> mentionedMobiles) {
|
||||
List<ZentaoTask> incompleteTasks,
|
||||
List<ZentaoBug> unresolvedBugs,
|
||||
ProjectInfo projectInfo,
|
||||
List<String> mentionedMobiles) {
|
||||
StringBuilder message = new StringBuilder();
|
||||
|
||||
// 消息头部
|
||||
@ -194,7 +194,7 @@ public class ZentaoTaskReminderService {
|
||||
for (ZentaoTask task : items.tasks) {
|
||||
String statusIcon = task.isOverdue() ? "🔴" : "⚪";
|
||||
message.append("- ").append(statusIcon).append(" [任务").append(task.getId()).append("] ")
|
||||
.append(task.getName());
|
||||
.append(task.getName());
|
||||
if (task.getDeadline() != null && !task.getDeadline().isEmpty() &&
|
||||
!"0000-00-00".equals(task.getDeadline())) {
|
||||
message.append(" (").append(task.getDeadline()).append(")");
|
||||
@ -206,7 +206,7 @@ public class ZentaoTaskReminderService {
|
||||
for (ZentaoBug bug : items.bugs) {
|
||||
String statusIcon = bug.isOverdue() ? "🔴" : "🐛";
|
||||
message.append("- ").append(statusIcon).append(" [BUG").append(bug.getId()).append("] ")
|
||||
.append(bug.getTitle());
|
||||
.append(bug.getTitle());
|
||||
if (bug.getSeverity() != null && !bug.getSeverity().isEmpty()) {
|
||||
message.append(" [").append(bug.getSeverityDesc()).append("]");
|
||||
}
|
||||
@ -277,6 +277,7 @@ public class ZentaoTaskReminderService {
|
||||
*/
|
||||
private static class ProjectItems {
|
||||
List<ZentaoTask> tasks = new ArrayList<>();
|
||||
|
||||
List<ZentaoBug> bugs = new ArrayList<>();
|
||||
}
|
||||
|
||||
@ -284,10 +285,10 @@ public class ZentaoTaskReminderService {
|
||||
* 构建任务提醒消息(保留原方法以兼容性)
|
||||
*/
|
||||
private String buildTaskReminderMessage(TaskReminderConfig.Group group,
|
||||
Map<String, List<ZentaoTask>> tasksByAssignee,
|
||||
List<ZentaoTask> allTasks,
|
||||
ProjectInfo projectInfo,
|
||||
List<String> mentionedMobiles) {
|
||||
Map<String, List<ZentaoTask>> tasksByAssignee,
|
||||
List<ZentaoTask> allTasks,
|
||||
ProjectInfo projectInfo,
|
||||
List<String> mentionedMobiles) {
|
||||
StringBuilder message = new StringBuilder();
|
||||
|
||||
// 简化消息头部
|
||||
@ -323,7 +324,7 @@ public class ZentaoTaskReminderService {
|
||||
String statusIcon = task.isOverdue() ? "🔴" : "⚪";
|
||||
|
||||
message.append("- ").append(statusIcon).append(" [").append(task.getId()).append("] ")
|
||||
.append(task.getName());
|
||||
.append(task.getName());
|
||||
|
||||
// 截止日期
|
||||
if (task.getDeadline() != null && !task.getDeadline().isEmpty() &&
|
||||
@ -346,10 +347,10 @@ public class ZentaoTaskReminderService {
|
||||
* 构建BUG提醒消息
|
||||
*/
|
||||
private String buildBugReminderMessage(TaskReminderConfig.Group group,
|
||||
Map<String, List<ZentaoBug>> bugsByAssignee,
|
||||
List<ZentaoBug> allBugs,
|
||||
ProjectInfo projectInfo,
|
||||
List<String> mentionedMobiles) {
|
||||
Map<String, List<ZentaoBug>> bugsByAssignee,
|
||||
List<ZentaoBug> allBugs,
|
||||
ProjectInfo projectInfo,
|
||||
List<String> mentionedMobiles) {
|
||||
StringBuilder message = new StringBuilder();
|
||||
|
||||
// 简化消息头部
|
||||
@ -385,7 +386,7 @@ public class ZentaoTaskReminderService {
|
||||
String statusIcon = bug.isOverdue() ? "🔴" : "🐛";
|
||||
|
||||
message.append("- ").append(statusIcon).append(" [").append(bug.getId()).append("] ")
|
||||
.append(bug.getTitle());
|
||||
.append(bug.getTitle());
|
||||
|
||||
// 严重程度
|
||||
if (bug.getSeverity() != null && !bug.getSeverity().isEmpty()) {
|
||||
@ -458,7 +459,6 @@ public class ZentaoTaskReminderService {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取任务详情(用于测试)
|
||||
*/
|
||||
|
||||
@ -16,7 +16,7 @@ public interface ReminderHandler {
|
||||
/**
|
||||
* 判断是否支持处理指定的提醒类型
|
||||
*
|
||||
* @param scheduleType 提醒类型
|
||||
* @param scheduleType 提醒类型
|
||||
* @param taskSystemType 任务系统类型
|
||||
* @return 是否支持
|
||||
*/
|
||||
|
||||
@ -27,7 +27,7 @@ public class ReminderHandlerFactory {
|
||||
/**
|
||||
* 获取合适的提醒处理器
|
||||
*
|
||||
* @param scheduleType 提醒类型
|
||||
* @param scheduleType 提醒类型
|
||||
* @param taskSystemType 任务系统类型
|
||||
* @return 提醒处理器,如果没有找到则返回null
|
||||
*/
|
||||
@ -49,7 +49,7 @@ public class ReminderHandlerFactory {
|
||||
* 获取合适的提醒处理器(字符串参数版本,用于兼容)
|
||||
*
|
||||
* @param scheduleTypeCode 提醒类型代码
|
||||
* @param taskSystemCode 任务系统类型代码
|
||||
* @param taskSystemCode 任务系统类型代码
|
||||
* @return 提醒处理器,如果没有找到则返回null
|
||||
*/
|
||||
public ReminderHandler getHandler(String scheduleTypeCode, String taskSystemCode) {
|
||||
|
||||
@ -35,11 +35,7 @@ public class TextReminderHandler implements ReminderHandler {
|
||||
logger.info("处理文本提醒 - 群组: {}, 类型: {}", group.getName(), scheduleType.getDescription());
|
||||
|
||||
// 生成带格式的提醒消息
|
||||
String message = wechatWebhookService.createTaskReminderMessage(
|
||||
group.getId(),
|
||||
schedule.getMessage(),
|
||||
scheduleType.getDescription()
|
||||
);
|
||||
String message = wechatWebhookService.createTaskReminderMessage(group.getId(), schedule.getMessage(), scheduleType.getDescription());
|
||||
|
||||
// 发送消息
|
||||
boolean success = wechatWebhookService.sendMarkdownMessage(group.getId(), message);
|
||||
|
||||
@ -31,7 +31,6 @@ public class HolidayUtil {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 初始化2025年节假日
|
||||
* 根据国务院办公厅2024年11月12日发布的《关于2025年部分节假日安排的通知》
|
||||
|
||||
Loading…
Reference in New Issue
Block a user