添加钉钉通知
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,3 +2,5 @@
|
||||
PPGo_Job
|
||||
|
||||
.idea
|
||||
|
||||
info.log
|
||||
@@ -10,16 +10,16 @@ jobs.pool = 1000
|
||||
# 站点名称
|
||||
site.name = 定时任务管理器
|
||||
|
||||
#通知方式 0=邮件,1=信息
|
||||
#通知方式 0=邮件,1=信息,2=钉钉
|
||||
notify.type = 0
|
||||
|
||||
|
||||
# 数据库配置
|
||||
db.host = db
|
||||
db.user = gotest
|
||||
db.password = "gotest"
|
||||
db.host = 127.0.0.1
|
||||
db.user = root
|
||||
db.password = "12345678"
|
||||
db.port = 3306
|
||||
db.name = local_gotest
|
||||
db.name = ppgo_job2
|
||||
db.prefix = pp_
|
||||
db.timezone = Asia/Shanghai
|
||||
|
||||
@@ -36,3 +36,7 @@ email.pool = 10
|
||||
msg.url = http://xx.com/api/tools/send_sms
|
||||
msg.pool = 10
|
||||
|
||||
|
||||
# 钉钉通知配置
|
||||
dingtalk.url = "https://oapi.dingtalk.com/robot/send?access_token=%s"
|
||||
dingtalk.pool = 10
|
||||
|
||||
@@ -58,6 +58,7 @@ func (self *AdminController) Edit() {
|
||||
row["real_name"] = Admin.RealName
|
||||
row["phone"] = Admin.Phone
|
||||
row["email"] = Admin.Email
|
||||
row["dingtalk"] = Admin.Dingtalk
|
||||
row["role_ids"] = Admin.RoleIds
|
||||
self.Data["admin"] = row
|
||||
|
||||
@@ -93,6 +94,7 @@ func (self *AdminController) AjaxSave() {
|
||||
Admin.RealName = strings.TrimSpace(self.GetString("real_name"))
|
||||
Admin.Phone = strings.TrimSpace(self.GetString("phone"))
|
||||
Admin.Email = strings.TrimSpace(self.GetString("email"))
|
||||
Admin.Dingtalk = strings.TrimSpace(self.GetString("dingtalk"))
|
||||
Admin.RoleIds = strings.TrimSpace(self.GetString("roleids"))
|
||||
Admin.UpdateTime = time.Now().Unix()
|
||||
Admin.UpdateId = self.userId
|
||||
@@ -125,6 +127,7 @@ func (self *AdminController) AjaxSave() {
|
||||
Admin.RealName = strings.TrimSpace(self.GetString("real_name"))
|
||||
Admin.Phone = strings.TrimSpace(self.GetString("phone"))
|
||||
Admin.Email = strings.TrimSpace(self.GetString("email"))
|
||||
Admin.Dingtalk = strings.TrimSpace(self.GetString("dingtalk"))
|
||||
Admin.RoleIds = strings.TrimSpace(self.GetString("roleids"))
|
||||
Admin.UpdateTime = time.Now().Unix()
|
||||
Admin.UpdateId = self.userId
|
||||
@@ -203,6 +206,7 @@ func (self *AdminController) Table() {
|
||||
row["real_name"] = v.RealName
|
||||
row["phone"] = v.Phone
|
||||
row["email"] = v.Email
|
||||
row["dingtalk"] = v.Dingtalk
|
||||
row["role_ids"] = v.RoleIds
|
||||
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")
|
||||
|
||||
27
jobs/job.go
27
jobs/job.go
@@ -279,6 +279,7 @@ func (j *Job) Run() {
|
||||
adminInfo := AllAdminInfo(j.task.NotifyUserIds)
|
||||
phone := make([]string, 0)
|
||||
toEmail := ""
|
||||
dingtalk := make([]string, 0)
|
||||
for _, v := range adminInfo {
|
||||
if v.Phone != "0" && v.Phone != "" {
|
||||
phone = append(phone, v.Phone)
|
||||
@@ -286,6 +287,9 @@ func (j *Job) Run() {
|
||||
if v.Email != "0" && v.Email != "" {
|
||||
toEmail += v.Email + ";"
|
||||
}
|
||||
if v.Dingtalk != "0" && v.Dingtalk != "" {
|
||||
dingtalk = append(dingtalk, v.Dingtalk)
|
||||
}
|
||||
}
|
||||
toEmail = strings.TrimRight(toEmail, ";")
|
||||
|
||||
@@ -346,6 +350,27 @@ func (j *Job) Run() {
|
||||
param["task_name"] = " " + j.task.TaskName
|
||||
param["status"] = " " + TextStatus[status]
|
||||
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
|
||||
Email string
|
||||
Phone string
|
||||
Dingtalk string
|
||||
RealName string
|
||||
}
|
||||
|
||||
@@ -388,6 +414,7 @@ func AllAdminInfo(adminIds string) []*adminInfo {
|
||||
Id: v.Id,
|
||||
Email: v.Email,
|
||||
Phone: v.Phone,
|
||||
Dingtalk: v.Dingtalk,
|
||||
RealName: v.RealName,
|
||||
}
|
||||
adminInfos = append(adminInfos, &ai)
|
||||
|
||||
20
libs/http.go
20
libs/http.go
@@ -13,6 +13,7 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"io"
|
||||
)
|
||||
|
||||
type AjaxReturn struct {
|
||||
@@ -56,3 +57,22 @@ func HttpGet(url string, param map[string]string) error {
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ type Admin struct {
|
||||
RoleIds string
|
||||
Phone string
|
||||
Email string
|
||||
Dingtalk string
|
||||
Salt string
|
||||
LastLogin int64
|
||||
LastIp string
|
||||
|
||||
95
notify/dingtalk.go
Normal file
95
notify/dingtalk.go
Normal 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
|
||||
}
|
||||
@@ -321,4 +321,12 @@ BEGIN;
|
||||
INSERT INTO `pp_user` VALUES ('1', 'admin', 'haodaquan@shoplinq.cn', 'abfcf6dcedfb4b5b1505d41a8b4c77e8', 'aYk4Q1P83v', '1528124357', '[', '0');
|
||||
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;
|
||||
|
||||
@@ -37,6 +37,14 @@
|
||||
<div class="layui-form-mid layui-word-aux">*</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">
|
||||
<label class="layui-form-label">选择角色</label>
|
||||
<div class="layui-input-block">
|
||||
|
||||
@@ -32,6 +32,13 @@
|
||||
<div class="layui-form-mid layui-word-aux">*</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">
|
||||
<label class="layui-form-label">重置密码</label>
|
||||
<div class="layui-input-inline">
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
,{field:'real_name', title: '真实姓名'}
|
||||
,{field:'phone', title: '联系电话'}
|
||||
,{field:'email', title: '电子邮箱'}
|
||||
,{field:'dingtalk', title: '钉钉通知'}
|
||||
,{field:'status_text', title: '状态'}
|
||||
,{fixed: 'right', width:160, align:'center', toolbar: '#bar'}
|
||||
]]
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
<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="1" title="短信" >
|
||||
<input type="radio" name="notify_type" lay-verify="required" value="2" title="钉钉" >
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux"></div>
|
||||
</div>
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
<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="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 class="layui-form-mid layui-word-aux"></div>
|
||||
</div>
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
{{if eq .task.IsNotify 1}}
|
||||
<tr>
|
||||
<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>
|
||||
</tr>
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
<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="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 class="layui-form-mid layui-word-aux"></div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user