添加钉钉通知

This commit is contained in:
linxiaozhi
2019-02-15 11:50:09 +08:00
parent fbd64d38a2
commit 5a7904a831
15 changed files with 186 additions and 6 deletions

2
.gitignore vendored
View File

@@ -2,3 +2,5 @@
PPGo_Job PPGo_Job
.idea .idea
info.log

View File

@@ -10,16 +10,16 @@ jobs.pool = 1000
# 站点名称 # 站点名称
site.name = 定时任务管理器 site.name = 定时任务管理器
#通知方式 0=邮件1=信息 #通知方式 0=邮件1=信息2=钉钉
notify.type = 0 notify.type = 0
# 数据库配置 # 数据库配置
db.host = db db.host = 127.0.0.1
db.user = gotest db.user = root
db.password = "gotest" db.password = "12345678"
db.port = 3306 db.port = 3306
db.name = local_gotest db.name = ppgo_job2
db.prefix = pp_ db.prefix = pp_
db.timezone = Asia/Shanghai db.timezone = Asia/Shanghai
@@ -36,3 +36,7 @@ email.pool = 10
msg.url = http://xx.com/api/tools/send_sms msg.url = http://xx.com/api/tools/send_sms
msg.pool = 10 msg.pool = 10
# 钉钉通知配置
dingtalk.url = "https://oapi.dingtalk.com/robot/send?access_token=%s"
dingtalk.pool = 10

View File

@@ -58,6 +58,7 @@ func (self *AdminController) Edit() {
row["real_name"] = Admin.RealName row["real_name"] = Admin.RealName
row["phone"] = Admin.Phone row["phone"] = Admin.Phone
row["email"] = Admin.Email row["email"] = Admin.Email
row["dingtalk"] = Admin.Dingtalk
row["role_ids"] = Admin.RoleIds row["role_ids"] = Admin.RoleIds
self.Data["admin"] = row self.Data["admin"] = row
@@ -93,6 +94,7 @@ func (self *AdminController) AjaxSave() {
Admin.RealName = strings.TrimSpace(self.GetString("real_name")) Admin.RealName = strings.TrimSpace(self.GetString("real_name"))
Admin.Phone = strings.TrimSpace(self.GetString("phone")) Admin.Phone = strings.TrimSpace(self.GetString("phone"))
Admin.Email = strings.TrimSpace(self.GetString("email")) Admin.Email = strings.TrimSpace(self.GetString("email"))
Admin.Dingtalk = strings.TrimSpace(self.GetString("dingtalk"))
Admin.RoleIds = strings.TrimSpace(self.GetString("roleids")) Admin.RoleIds = strings.TrimSpace(self.GetString("roleids"))
Admin.UpdateTime = time.Now().Unix() Admin.UpdateTime = time.Now().Unix()
Admin.UpdateId = self.userId Admin.UpdateId = self.userId
@@ -125,6 +127,7 @@ func (self *AdminController) AjaxSave() {
Admin.RealName = strings.TrimSpace(self.GetString("real_name")) Admin.RealName = strings.TrimSpace(self.GetString("real_name"))
Admin.Phone = strings.TrimSpace(self.GetString("phone")) Admin.Phone = strings.TrimSpace(self.GetString("phone"))
Admin.Email = strings.TrimSpace(self.GetString("email")) Admin.Email = strings.TrimSpace(self.GetString("email"))
Admin.Dingtalk = strings.TrimSpace(self.GetString("dingtalk"))
Admin.RoleIds = strings.TrimSpace(self.GetString("roleids")) Admin.RoleIds = strings.TrimSpace(self.GetString("roleids"))
Admin.UpdateTime = time.Now().Unix() Admin.UpdateTime = time.Now().Unix()
Admin.UpdateId = self.userId Admin.UpdateId = self.userId
@@ -203,6 +206,7 @@ func (self *AdminController) Table() {
row["real_name"] = v.RealName row["real_name"] = v.RealName
row["phone"] = v.Phone row["phone"] = v.Phone
row["email"] = v.Email row["email"] = v.Email
row["dingtalk"] = v.Dingtalk
row["role_ids"] = v.RoleIds row["role_ids"] = v.RoleIds
row["create_time"] = beego.Date(time.Unix(v.CreateTime, 0), "Y-m-d H:i:s") row["create_time"] = beego.Date(time.Unix(v.CreateTime, 0), "Y-m-d H:i:s")
row["update_time"] = beego.Date(time.Unix(v.UpdateTime, 0), "Y-m-d H:i:s") row["update_time"] = beego.Date(time.Unix(v.UpdateTime, 0), "Y-m-d H:i:s")

View File

@@ -279,6 +279,7 @@ func (j *Job) Run() {
adminInfo := AllAdminInfo(j.task.NotifyUserIds) adminInfo := AllAdminInfo(j.task.NotifyUserIds)
phone := make([]string, 0) phone := make([]string, 0)
toEmail := "" toEmail := ""
dingtalk := make([]string, 0)
for _, v := range adminInfo { for _, v := range adminInfo {
if v.Phone != "0" && v.Phone != "" { if v.Phone != "0" && v.Phone != "" {
phone = append(phone, v.Phone) phone = append(phone, v.Phone)
@@ -286,6 +287,9 @@ func (j *Job) Run() {
if v.Email != "0" && v.Email != "" { if v.Email != "0" && v.Email != "" {
toEmail += v.Email + ";" toEmail += v.Email + ";"
} }
if v.Dingtalk != "0" && v.Dingtalk != "" {
dingtalk = append(dingtalk, v.Dingtalk)
}
} }
toEmail = strings.TrimRight(toEmail, ";") toEmail = strings.TrimRight(toEmail, ";")
@@ -346,6 +350,27 @@ func (j *Job) Run() {
param["task_name"] = " " + j.task.TaskName param["task_name"] = " " + j.task.TaskName
param["status"] = " " + TextStatus[status] param["status"] = " " + TextStatus[status]
notify.SendSmsToChan(phone, param) notify.SendSmsToChan(phone, param)
} else if j.task.NotifyType == 2 && len(dingtalk) > 0 {
content := fmt.Sprintf(
`定时任务异常:%s\n
任务执行详情:\n
任务 ID%d\n
任务名称:%s\n
执行时间:%s\n
执行耗时:%f秒\n
执行状态:%s\n
任务执行输出\n
%s`,
j.task.TaskName,
j.task.Id,
j.task.TaskName,
beego.Date(time.Unix(log.CreateTime, 0), "Y-m-d H:i:s"),
float64(log.ProcessTime)/1000,
TextStatus[status],
log.Error)
notify.SendDingtalkToChan(dingtalk, content)
} }
} }
@@ -364,6 +389,7 @@ type adminInfo struct {
Id int Id int
Email string Email string
Phone string Phone string
Dingtalk string
RealName string RealName string
} }
@@ -388,6 +414,7 @@ func AllAdminInfo(adminIds string) []*adminInfo {
Id: v.Id, Id: v.Id,
Email: v.Email, Email: v.Email,
Phone: v.Phone, Phone: v.Phone,
Dingtalk: v.Dingtalk,
RealName: v.RealName, RealName: v.RealName,
} }
adminInfos = append(adminInfos, &ai) adminInfos = append(adminInfos, &ai)

View File

@@ -13,6 +13,7 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"strings" "strings"
"io"
) )
type AjaxReturn struct { type AjaxReturn struct {
@@ -56,3 +57,22 @@ func HttpGet(url string, param map[string]string) error {
} }
return nil return nil
} }
func HttpPost(url string, contentType string, body io.Reader) error {
resp, err := http.Post(url, contentType, body)
if err != nil {
return err
}
defer resp.Body.Close()
_, resErr := ioutil.ReadAll(resp.Body)
if resErr != nil {
return resErr
}
return nil
}

View File

@@ -19,6 +19,7 @@ type Admin struct {
RoleIds string RoleIds string
Phone string Phone string
Email string Email string
Dingtalk string
Salt string Salt string
LastLogin int64 LastLogin int64
LastIp string LastIp string

95
notify/dingtalk.go Normal file
View File

@@ -0,0 +1,95 @@
/************************************************************
** @Description: notify
** @Author: Bee
** @Date: 2018-02-15 11:02
** @Last Modified by: Bee
** @Last Modified time: 2018-02-15 11:02
*************************************************************/
package notify
import (
"github.com/astaxie/beego"
"github.com/george518/PPGo_Job/libs"
"log"
"time"
"fmt"
"encoding/json"
"bytes"
)
type Dingtalk struct {
Dingtalks []string
Content string
}
var DingtalkChan chan *Dingtalk
var DingtalkUrl string
func init() {
DingtalkUrl = beego.AppConfig.String("dingtalk.url")
poolSize, _ := beego.AppConfig.Int("dingtalk.pool")
//创建通道
DingtalkChan = make(chan *Dingtalk, poolSize)
go func() {
for {
select {
case m, ok := <-DingtalkChan:
if !ok {
return
}
if err := m.SendDingtalk(); err != nil {
beego.Error("SendDingtalk:", err.Error())
}
}
}
}()
}
func SendDingtalkToChan(dingtalks []string, content string) bool {
dingTalk := &Dingtalk{
Dingtalks: dingtalks,
Content: content,
}
select {
case DingtalkChan <- dingTalk:
return true
case <-time.After(time.Second * 3):
return false
}
}
type Msg struct {
MsgType string `json:"msgtype"`
Text *Text `json:"text"`
}
type Text struct {
Content string `json:"content"`
}
func (s *Dingtalk) SendDingtalk() error {
for _, v := range s.Dingtalks {
msg := Msg{MsgType: "text"}
text := new(Text)
text.Content = s.Content
msg.Text = text
msgJson, err := json.Marshal(msg)
if err != nil {
log.Println(err)
}
url := fmt.Sprintf(DingtalkUrl, v)
resErr := libs.HttpPost(url, "application/json;charset=utf-8", bytes.NewBuffer(msgJson))
if resErr != nil {
log.Println(err)
}
}
return nil
}

View File

@@ -321,4 +321,12 @@ BEGIN;
INSERT INTO `pp_user` VALUES ('1', 'admin', 'haodaquan@shoplinq.cn', 'abfcf6dcedfb4b5b1505d41a8b4c77e8', 'aYk4Q1P83v', '1528124357', '[', '0'); INSERT INTO `pp_user` VALUES ('1', 'admin', 'haodaquan@shoplinq.cn', 'abfcf6dcedfb4b5b1505d41a8b4c77e8', 'aYk4Q1P83v', '1528124357', '[', '0');
COMMIT; COMMIT;
BEGIN;
ALTER TABLE `pp_task` CHANGE `notify_type` `notify_type` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0' COMMENT '0-邮件通知1-信息通知2-钉钉通知,';
COMMIT;
BEGIN;
ALTER TABLE `pp_uc_admin` ADD `dingtalk` VARCHAR(64) NULL COMMENT '钉钉' AFTER `email`;
COMMIT;
SET FOREIGN_KEY_CHECKS = 1; SET FOREIGN_KEY_CHECKS = 1;

View File

@@ -37,6 +37,14 @@
<div class="layui-form-mid layui-word-aux">*</div> <div class="layui-form-mid layui-word-aux">*</div>
</div> </div>
<div class="layui-form-item">
<label class="layui-form-label">钉钉通知</label>
<div class="layui-input-inline">
<input type="text" name="dingtalk" id="dingtalk" autocomplete="off" placeholder="钉钉通知" class="layui-input" value="">
</div>
<div class="layui-form-mid layui-word-aux">*</div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">选择角色</label> <label class="layui-form-label">选择角色</label>
<div class="layui-input-block"> <div class="layui-input-block">

View File

@@ -32,6 +32,13 @@
<div class="layui-form-mid layui-word-aux">*</div> <div class="layui-form-mid layui-word-aux">*</div>
</div> </div>
<div class="layui-form-item">
<label class="layui-form-label">钉钉通知</label>
<div class="layui-input-inline">
<input type="text" name="dingtalk" id="dingtalk" autocomplete="off" placeholder="钉钉通知" class="layui-input" value="{{.admin.dingtalk}}">
</div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">重置密码</label> <label class="layui-form-label">重置密码</label>
<div class="layui-input-inline"> <div class="layui-input-inline">

View File

@@ -52,6 +52,7 @@
,{field:'real_name', title: '真实姓名'} ,{field:'real_name', title: '真实姓名'}
,{field:'phone', title: '联系电话'} ,{field:'phone', title: '联系电话'}
,{field:'email', title: '电子邮箱'} ,{field:'email', title: '电子邮箱'}
,{field:'dingtalk', title: '钉钉通知'}
,{field:'status_text', title: '状态'} ,{field:'status_text', title: '状态'}
,{fixed: 'right', width:160, align:'center', toolbar: '#bar'} ,{fixed: 'right', width:160, align:'center', toolbar: '#bar'}
]] ]]

View File

@@ -99,6 +99,7 @@
<div class="layui-input-inline "> <div class="layui-input-inline ">
<input type="radio" name="notify_type" lay-verify="required" value="0" title="邮件" checked> <input type="radio" name="notify_type" lay-verify="required" value="0" title="邮件" checked>
<input type="radio" name="notify_type" lay-verify="required" value="1" title="短信" > <input type="radio" name="notify_type" lay-verify="required" value="1" title="短信" >
<input type="radio" name="notify_type" lay-verify="required" value="2" title="钉钉" >
</div> </div>
<div class="layui-form-mid layui-word-aux"></div> <div class="layui-form-mid layui-word-aux"></div>
</div> </div>

View File

@@ -100,6 +100,7 @@
<div class="layui-input-inline "> <div class="layui-input-inline ">
<input type="radio" name="notify_type" lay-verify="required" value="0" title="邮件" {{if eq .task.NotifyType 0}}checked{{end}}> <input type="radio" name="notify_type" lay-verify="required" value="0" title="邮件" {{if eq .task.NotifyType 0}}checked{{end}}>
<input type="radio" name="notify_type" lay-verify="required" value="1" title="短信" {{if eq .task.NotifyType 1}}checked{{end}}> <input type="radio" name="notify_type" lay-verify="required" value="1" title="短信" {{if eq .task.NotifyType 1}}checked{{end}}>
<input type="radio" name="notify_type" lay-verify="required" value="2" title="钉钉" {{if eq .task.NotifyType 2}}checked{{end}}>
</div> </div>
<div class="layui-form-mid layui-word-aux"></div> <div class="layui-form-mid layui-word-aux"></div>
</div> </div>

View File

@@ -99,7 +99,7 @@
{{if eq .task.IsNotify 1}} {{if eq .task.IsNotify 1}}
<tr> <tr>
<td>通知类型</td> <td>通知类型</td>
<td>{{if eq .task.NotifyType 1}}短信{{end}} {{if eq .task.NotifyType 0}}邮件{{end}}</td> <td>{{if eq .task.NotifyType 1}}短信{{end}} {{if eq .task.NotifyType 0}}邮件{{end}} {{if eq .task.NotifyType 2}}钉钉{{end}}</td>
<td></td> <td></td>
</tr> </tr>

View File

@@ -99,6 +99,7 @@
<div class="layui-input-inline "> <div class="layui-input-inline ">
<input type="radio" name="notify_type" lay-verify="required" value="0" title="邮件" {{if eq .task.NotifyType 0}}checked{{end}}> <input type="radio" name="notify_type" lay-verify="required" value="0" title="邮件" {{if eq .task.NotifyType 0}}checked{{end}}>
<input type="radio" name="notify_type" lay-verify="required" value="1" title="短信" {{if eq .task.NotifyType 1}}checked{{end}}> <input type="radio" name="notify_type" lay-verify="required" value="1" title="短信" {{if eq .task.NotifyType 1}}checked{{end}}>
<input type="radio" name="notify_type" lay-verify="required" value="2" title="钉钉" {{if eq .task.NotifyType 2}}checked{{end}}>
</div> </div>
<div class="layui-form-mid layui-word-aux"></div> <div class="layui-form-mid layui-word-aux"></div>
</div> </div>