添加钉钉通知
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,3 +2,5 @@
|
|||||||
PPGo_Job
|
PPGo_Job
|
||||||
|
|
||||||
.idea
|
.idea
|
||||||
|
|
||||||
|
info.log
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
27
jobs/job.go
27
jobs/job.go
@@ -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)
|
||||||
|
|||||||
20
libs/http.go
20
libs/http.go
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
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');
|
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;
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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'}
|
||||||
]]
|
]]
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user