diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/WeiUtils/WebHookMessage.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/WeiUtils/WebHookMessage.java
new file mode 100644
index 00000000..bee8ce6a
--- /dev/null
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/WeiUtils/WebHookMessage.java
@@ -0,0 +1,50 @@
+package com.xxl.job.admin.core.alarm.WeiUtils;
+
+
+/**
+ * @author change
+ * @date 2022-09-22 0022 02:52:55
+ */
+public class WebHookMessage {
+ private String webHook;
+ private String msgtype;
+ private Markdown markdown;
+
+ public String getWebHook() {
+ return webHook;
+ }
+
+ public void setWebHook(String webHook) {
+ this.webHook = webHook;
+ }
+
+ public String getMsgtype() {
+ return msgtype;
+ }
+
+ public void setMsgtype(String msgtype) {
+ this.msgtype = msgtype;
+ }
+
+ public Markdown getMarkdown() {
+ return markdown;
+ }
+
+ public void setMarkdown(Markdown markdown) {
+ this.markdown = markdown;
+ }
+
+ public static class Markdown {
+ private String content;
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+ }
+
+
+}
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/impl/WeiJobAlarm.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/impl/WeiJobAlarm.java
new file mode 100644
index 00000000..629fa303
--- /dev/null
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/impl/WeiJobAlarm.java
@@ -0,0 +1,89 @@
+package com.xxl.job.admin.core.alarm.impl;
+
+import com.xxl.job.admin.core.alarm.JobAlarm;
+import com.xxl.job.admin.core.alarm.WeiUtils.WebHookMessage;
+import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
+import com.xxl.job.admin.core.model.XxlJobGroup;
+import com.xxl.job.admin.core.model.XxlJobInfo;
+import com.xxl.job.admin.core.model.XxlJobLog;
+import com.xxl.job.admin.core.util.I18nUtil;
+import com.xxl.job.core.biz.model.ReturnT;
+import com.xxl.job.core.util.DateUtil;
+import com.xxl.job.core.util.GsonTool;
+import com.xxl.job.core.util.XxlJobRemotingUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+/**
+ * 发送企业微信机器人消息
+ *
+ * @author change
+ * @date 2023-03-22 0022 11:20:30
+ */
+@Component
+public class WeiJobAlarm implements JobAlarm {
+ private static final Logger logger = LoggerFactory.getLogger(WeiJobAlarm.class);
+
+ /**
+ * fail alarm
+ *
+ * @param jobLog
+ */
+ @Override
+ public boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog) {
+ boolean alarmResult = true;
+
+ // send monitor webhook
+ if (info != null && info.getAlarmWei() != null && info.getAlarmWei().trim().length() > 0) {
+
+ // alarmContent
+ String alarmContent = "Alarm Job LogId=" + jobLog.getId();
+ if (jobLog.getTriggerCode() != ReturnT.SUCCESS_CODE) {
+ alarmContent += "\nTriggerMsg=\n" + jobLog.getTriggerMsg().replaceAll("
", "|| ");
+ }
+ if (jobLog.getHandleCode() > 0 && jobLog.getHandleCode() != ReturnT.SUCCESS_CODE) {
+ alarmContent += "\nHandleCode=" + jobLog.getHandleMsg();
+ }
+
+ // info
+ XxlJobGroup group = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().load(info.getJobGroup());
+
+ String content = loadEmailJobAlarmTemplate(info.getJobDesc(), group.getTitle(), info.getId(), alarmContent);
+
+ String webhookUrl = info.getAlarmWei().trim();
+
+ WebHookMessage message = new WebHookMessage();
+ message.setMsgtype("markdown");
+ WebHookMessage.Markdown markdown = new WebHookMessage.Markdown();
+ markdown.setContent(content);
+ message.setMarkdown(markdown);
+ ReturnT returnT = XxlJobRemotingUtil.postBody(webhookUrl, null, 3, message, String.class);
+ logger.info("请求结果:{}", GsonTool.toJson(returnT));
+ }
+
+ return alarmResult;
+ }
+
+ /**
+ * 企业微信机器人消息模板
+ *
+ * @return 模板
+ */
+ private static String loadEmailJobAlarmTemplate(String jobDesc, String jobGroup, int taskId, String content) {
+ return "# " + jobDesc + "\n"
+ + "> 时间: " + DateUtil.formatDateTime(new Date()) + "\n"
+ + "> `**事项详情**` \n"
+ //执行器
+ + "> " + I18nUtil.getString("jobinfo_field_jobgroup") + ":" + jobGroup + " \n"
+ //任务id
+ + "> " + I18nUtil.getString("jobinfo_field_id") + ":" + taskId + "\n"
+ //告警类型
+ + "> " + I18nUtil.getString("jobconf_monitor_alarm_title") + ":" + I18nUtil.getString("jobconf_monitor_alarm_type") + "\n"
+ //告警内容
+ + "> " + I18nUtil.getString("jobconf_monitor_alarm_content") + ":\n" + content + " \n";
+ }
+
+}
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java
index e47b6dc6..7ffbcfdb 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java
@@ -19,6 +19,7 @@ public class XxlJobInfo {
private String author; // 负责人
private String alarmEmail; // 报警邮件
+ private String alarmWei; // 企业微信群机器人告警
private String scheduleType; // 调度类型
private String scheduleConf; // 调度配置,值含义取决于调度类型
@@ -99,6 +100,14 @@ public class XxlJobInfo {
this.alarmEmail = alarmEmail;
}
+ public String getAlarmWei() {
+ return alarmWei;
+ }
+
+ public void setAlarmWei(String alarmWei) {
+ this.alarmWei = alarmWei;
+ }
+
public String getScheduleType() {
return scheduleType;
}
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobFailMonitorHelper.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobFailMonitorHelper.java
index 8409d7b3..2834e1dc 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobFailMonitorHelper.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobFailMonitorHelper.java
@@ -60,7 +60,8 @@ public class JobFailMonitorHelper {
// 2、fail alarm monitor
int newAlarmStatus = 0; // 告警状态:0-默认、-1=锁定状态、1-无需告警、2-告警成功、3-告警失败
- if (info != null) {
+ if (info != null && ((info.getAlarmEmail() != null && info.getAlarmEmail().trim().length() > 0)
+ || (info.getAlarmWei() != null && info.getAlarmWei().trim().length() > 0))) {
boolean alarmResult = XxlJobAdminConfig.getAdminConfig().getJobAlarmer().alarm(info, log);
newAlarmStatus = alarmResult?2:3;
} else {
diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java
index 530ee41c..c611749e 100644
--- a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java
+++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java
@@ -268,6 +268,7 @@ public class XxlJobServiceImpl implements XxlJobService {
exists_jobInfo.setJobDesc(jobInfo.getJobDesc());
exists_jobInfo.setAuthor(jobInfo.getAuthor());
exists_jobInfo.setAlarmEmail(jobInfo.getAlarmEmail());
+ exists_jobInfo.setAlarmWei(jobInfo.getAlarmWei());
exists_jobInfo.setScheduleType(jobInfo.getScheduleType());
exists_jobInfo.setScheduleConf(jobInfo.getScheduleConf());
exists_jobInfo.setMisfireStrategy(jobInfo.getMisfireStrategy());
diff --git a/xxl-job-admin/src/main/resources/i18n/message_zh_CN.properties b/xxl-job-admin/src/main/resources/i18n/message_zh_CN.properties
index 7891570d..41582a23 100644
--- a/xxl-job-admin/src/main/resources/i18n/message_zh_CN.properties
+++ b/xxl-job-admin/src/main/resources/i18n/message_zh_CN.properties
@@ -120,6 +120,8 @@ jobinfo_field_author=负责人
jobinfo_field_timeout=任务超时时间
jobinfo_field_alarmemail=报警邮件
jobinfo_field_alarmemail_placeholder=请输入报警邮件,多个邮件地址则逗号分隔
+jobinfo_field_weimail=企业微信告警
+jobinfo_field_weimail_placeholder=请输入机器人地址
jobinfo_field_executorRouteStrategy=路由策略
jobinfo_field_childJobId=子任务ID
jobinfo_field_childJobId_placeholder=请输入子任务的任务ID,如存在多个则逗号分隔
diff --git a/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml
index 7b3c3a3e..65cabfef 100644
--- a/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml
+++ b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml
@@ -14,6 +14,7 @@
${I18n.jobinfo_conf_schedule}
<#-- 调度 -->${I18n.jobinfo_conf_schedule}
<#-- 调度配置 -->