新增任务失败邮件提醒
任务异常提醒软件
This commit is contained in:
@@ -10,6 +10,9 @@ jobs.pool = 1000
|
|||||||
# 站点名称
|
# 站点名称
|
||||||
site.name = 定时任务管理器
|
site.name = 定时任务管理器
|
||||||
|
|
||||||
|
#通知方式 0=邮件,1=信息
|
||||||
|
notify.type = 0
|
||||||
|
|
||||||
|
|
||||||
# 数据库配置
|
# 数据库配置
|
||||||
db.host = 127.0.0.1
|
db.host = 127.0.0.1
|
||||||
@@ -19,3 +22,16 @@ db.port = 3306
|
|||||||
db.name = ppgo_job2
|
db.name = ppgo_job2
|
||||||
db.prefix = pp_
|
db.prefix = pp_
|
||||||
db.timezone = Asia/Shanghai
|
db.timezone = Asia/Shanghai
|
||||||
|
|
||||||
|
# 邮件通知配置
|
||||||
|
email.host = smtp.mxhichina.com
|
||||||
|
email.port = 25
|
||||||
|
email.from = ci@xxx.cn
|
||||||
|
email.user = ci@xxx.cn
|
||||||
|
email.password = "xxx@123"
|
||||||
|
email.pool = 10
|
||||||
|
|
||||||
|
|
||||||
|
# 其他通知方式
|
||||||
|
msg.url = http://xxx.com/sms/url?id=12&msg=12121
|
||||||
|
|
||||||
|
|||||||
@@ -285,6 +285,42 @@ func serverListByGroupId(groupId int) []string {
|
|||||||
return servers
|
return servers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type adminInfo struct {
|
||||||
|
Id int
|
||||||
|
Email string
|
||||||
|
Phone string
|
||||||
|
RealName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func AllAdminInfo(adminIds string) []*adminInfo {
|
||||||
|
Filters := make([]interface{}, 0)
|
||||||
|
Filters = append(Filters, "status", 1)
|
||||||
|
//Filters = append(Filters, "id__gt", 1)
|
||||||
|
var notifyUserIds []int
|
||||||
|
if adminIds != "0" && adminIds != "" {
|
||||||
|
notifyUserIdsStr := strings.Split(adminIds, ",")
|
||||||
|
for _, v := range notifyUserIdsStr {
|
||||||
|
i, _ := strconv.Atoi(v)
|
||||||
|
notifyUserIds = append(notifyUserIds, i)
|
||||||
|
}
|
||||||
|
Filters = append(Filters, "id__in", notifyUserIds)
|
||||||
|
}
|
||||||
|
Result, _ := models.AdminGetList(1, 1000, Filters...)
|
||||||
|
|
||||||
|
adminInfos := make([]*adminInfo, 0)
|
||||||
|
for _, v := range Result {
|
||||||
|
ai := adminInfo{
|
||||||
|
Id: v.Id,
|
||||||
|
Email: v.Email,
|
||||||
|
Phone: v.Phone,
|
||||||
|
RealName: v.RealName,
|
||||||
|
}
|
||||||
|
adminInfos = append(adminInfos, &ai)
|
||||||
|
}
|
||||||
|
|
||||||
|
return adminInfos
|
||||||
|
}
|
||||||
|
|
||||||
type serverList struct {
|
type serverList struct {
|
||||||
GroupId int
|
GroupId int
|
||||||
GroupName string
|
GroupName string
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ func (self *RoleController) Edit() {
|
|||||||
row["id"] = role.Id
|
row["id"] = role.Id
|
||||||
row["role_name"] = role.RoleName
|
row["role_name"] = role.RoleName
|
||||||
row["detail"] = role.Detail
|
row["detail"] = role.Detail
|
||||||
row["detail"] = role.Detail
|
|
||||||
row["task_group_ids"] = role.TaskGroupIds
|
row["task_group_ids"] = role.TaskGroupIds
|
||||||
row["server_group_ids"] = role.ServerGroupIds
|
row["server_group_ids"] = role.ServerGroupIds
|
||||||
self.Data["role"] = row
|
self.Data["role"] = row
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"fmt"
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
"github.com/george518/PPGo_Job/jobs"
|
"github.com/george518/PPGo_Job/jobs"
|
||||||
"github.com/george518/PPGo_Job/models"
|
"github.com/george518/PPGo_Job/models"
|
||||||
@@ -38,6 +39,9 @@ func (self *TaskController) Add() {
|
|||||||
self.Data["taskGroup"] = taskGroupLists(self.taskGroups, self.userId)
|
self.Data["taskGroup"] = taskGroupLists(self.taskGroups, self.userId)
|
||||||
self.Data["serverGroup"] = serverLists(self.serverGroups, self.userId)
|
self.Data["serverGroup"] = serverLists(self.serverGroups, self.userId)
|
||||||
self.Data["isAdmin"] = self.userId
|
self.Data["isAdmin"] = self.userId
|
||||||
|
self.Data["adminInfo"] = AllAdminInfo("")
|
||||||
|
|
||||||
|
fmt.Println(self.Data["adminInfo"])
|
||||||
self.display()
|
self.display()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,15 +59,28 @@ func (self *TaskController) Edit() {
|
|||||||
}
|
}
|
||||||
self.Data["task"] = task
|
self.Data["task"] = task
|
||||||
|
|
||||||
|
self.Data["adminInfo"] = AllAdminInfo("")
|
||||||
|
|
||||||
// 分组列表
|
// 分组列表
|
||||||
self.Data["taskGroup"] = taskGroupLists(self.taskGroups, self.userId)
|
self.Data["taskGroup"] = taskGroupLists(self.taskGroups, self.userId)
|
||||||
self.Data["serverGroup"] = serverLists(self.serverGroups, self.userId)
|
self.Data["serverGroup"] = serverLists(self.serverGroups, self.userId)
|
||||||
self.Data["isAdmin"] = self.userId
|
self.Data["isAdmin"] = self.userId
|
||||||
|
var notifyUserIds []int
|
||||||
|
if task.NotifyUserIds != "0" {
|
||||||
|
notifyUserIdsStr := strings.Split(task.NotifyUserIds, ",")
|
||||||
|
for _, v := range notifyUserIdsStr {
|
||||||
|
i, _ := strconv.Atoi(v)
|
||||||
|
notifyUserIds = append(notifyUserIds, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.Data["notify_user_ids"] = notifyUserIds
|
||||||
self.display()
|
self.display()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *TaskController) Copy() {
|
func (self *TaskController) Copy() {
|
||||||
self.Data["pageTitle"] = "复制任务"
|
self.Data["pageTitle"] = "复制任务"
|
||||||
|
self.Data["adminInfo"] = AllAdminInfo("")
|
||||||
|
|
||||||
id, _ := self.GetInt("id")
|
id, _ := self.GetInt("id")
|
||||||
task, err := models.TaskGetById(id)
|
task, err := models.TaskGetById(id)
|
||||||
@@ -75,6 +92,15 @@ func (self *TaskController) Copy() {
|
|||||||
// 分组列表
|
// 分组列表
|
||||||
self.Data["taskGroup"] = taskGroupLists(self.taskGroups, self.userId)
|
self.Data["taskGroup"] = taskGroupLists(self.taskGroups, self.userId)
|
||||||
self.Data["serverGroup"] = serverLists(self.serverGroups, self.userId)
|
self.Data["serverGroup"] = serverLists(self.serverGroups, self.userId)
|
||||||
|
var notifyUserIds []int
|
||||||
|
if task.NotifyUserIds != "0" {
|
||||||
|
notifyUserIdsStr := strings.Split(task.NotifyUserIds, ",")
|
||||||
|
for _, v := range notifyUserIdsStr {
|
||||||
|
i, _ := strconv.Atoi(v)
|
||||||
|
notifyUserIds = append(notifyUserIds, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.Data["notify_user_ids"] = notifyUserIds
|
||||||
self.display()
|
self.display()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +164,13 @@ func (self *TaskController) Detail() {
|
|||||||
updateName = admin.RealName
|
updateName = admin.RealName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//是否出错通知
|
||||||
|
self.Data["adminInfo"] = []int{0}
|
||||||
|
fmt.Println(task.NotifyUserIds)
|
||||||
|
if task.NotifyUserIds != "0" && task.NotifyUserIds != "" {
|
||||||
|
self.Data["adminInfo"] = AllAdminInfo(task.NotifyUserIds)
|
||||||
|
}
|
||||||
self.Data["CreateName"] = createName
|
self.Data["CreateName"] = createName
|
||||||
self.Data["UpdateName"] = updateName
|
self.Data["UpdateName"] = updateName
|
||||||
self.Data["serverName"] = serverName
|
self.Data["serverName"] = serverName
|
||||||
@@ -157,6 +190,9 @@ func (self *TaskController) AjaxSave() {
|
|||||||
task.CronSpec = strings.TrimSpace(self.GetString("cron_spec"))
|
task.CronSpec = strings.TrimSpace(self.GetString("cron_spec"))
|
||||||
task.Command = strings.TrimSpace(self.GetString("command"))
|
task.Command = strings.TrimSpace(self.GetString("command"))
|
||||||
task.Timeout, _ = self.GetInt("timeout")
|
task.Timeout, _ = self.GetInt("timeout")
|
||||||
|
task.IsNotify, _ = self.GetInt("is_notify")
|
||||||
|
task.NotifyType, _ = self.GetInt("notify_type")
|
||||||
|
task.NotifyUserIds = strings.TrimSpace(self.GetString("notify_user_ids"))
|
||||||
|
|
||||||
msg, isBan := checkCommand(task.Command)
|
msg, isBan := checkCommand(task.Command)
|
||||||
if !isBan {
|
if !isBan {
|
||||||
@@ -194,6 +230,9 @@ func (self *TaskController) AjaxSave() {
|
|||||||
task.CronSpec = strings.TrimSpace(self.GetString("cron_spec"))
|
task.CronSpec = strings.TrimSpace(self.GetString("cron_spec"))
|
||||||
task.Command = strings.TrimSpace(self.GetString("command"))
|
task.Command = strings.TrimSpace(self.GetString("command"))
|
||||||
task.Timeout, _ = self.GetInt("timeout")
|
task.Timeout, _ = self.GetInt("timeout")
|
||||||
|
task.IsNotify, _ = self.GetInt("is_notify")
|
||||||
|
task.NotifyType, _ = self.GetInt("notify_type")
|
||||||
|
task.NotifyUserIds = strings.TrimSpace(self.GetString("notify_user_ids"))
|
||||||
task.UpdateId = self.userId
|
task.UpdateId = self.userId
|
||||||
task.Status = 2 //审核中,超级管理员不需要
|
task.Status = 2 //审核中,超级管理员不需要
|
||||||
if self.userId == 1 {
|
if self.userId == 1 {
|
||||||
|
|||||||
125
jobs/job.go
125
jobs/job.go
@@ -18,7 +18,10 @@ import (
|
|||||||
|
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
"github.com/george518/PPGo_Job/models"
|
"github.com/george518/PPGo_Job/models"
|
||||||
|
"github.com/george518/PPGo_Job/notify"
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Job struct {
|
type Job struct {
|
||||||
@@ -187,7 +190,6 @@ func RemoteCommandJobByPassword(id int, name string, command string, servers *mo
|
|||||||
var c bytes.Buffer
|
var c bytes.Buffer
|
||||||
session.Stdout = &b
|
session.Stdout = &b
|
||||||
session.Stderr = &c
|
session.Stderr = &c
|
||||||
|
|
||||||
//session.Output(command)
|
//session.Output(command)
|
||||||
if err := session.Run(command); err != nil {
|
if err := session.Run(command); err != nil {
|
||||||
return "", "", err, false
|
return "", "", err, false
|
||||||
@@ -264,6 +266,90 @@ func (j *Job) Run() {
|
|||||||
log.Status = models.TASK_ERROR
|
log.Status = models.TASK_ERROR
|
||||||
log.Error = err.Error() + ":" + cmdErr
|
log.Error = err.Error() + ":" + cmdErr
|
||||||
}
|
}
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println(log.Status, j.task.IsNotify)
|
||||||
|
|
||||||
|
if log.Status < 0 && j.task.IsNotify == 1 {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println(j.task.NotifyUserIds)
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println(j.task.NotifyUserIds != "0")
|
||||||
|
fmt.Println(j.task.NotifyUserIds != "")
|
||||||
|
if j.task.NotifyUserIds != "0" && j.task.NotifyUserIds != "" {
|
||||||
|
admin_info := AllAdminInfo(j.task.NotifyUserIds)
|
||||||
|
fmt.Println("ADMIN:", admin_info)
|
||||||
|
phone := make([]string, 0)
|
||||||
|
toEmail := ""
|
||||||
|
for _, v := range admin_info {
|
||||||
|
if v.Phone != "0" && v.Phone != "" {
|
||||||
|
phone = append(phone, v.Phone)
|
||||||
|
}
|
||||||
|
if v.Email != "0" && v.Email != "" {
|
||||||
|
toEmail += v.Email + ";"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toEmail = strings.TrimRight(toEmail, ";")
|
||||||
|
|
||||||
|
fmt.Println("EMAIL:", toEmail)
|
||||||
|
fmt.Println("TYPE:", j.task.NotifyType)
|
||||||
|
|
||||||
|
TextStatus := []string{
|
||||||
|
"<font color='red'>超时</font>",
|
||||||
|
"<font color='red'>错误</font>",
|
||||||
|
"<font color='green'>正常</font>",
|
||||||
|
}
|
||||||
|
|
||||||
|
status := log.Status + 2
|
||||||
|
|
||||||
|
if j.task.NotifyType == 0 && toEmail != "" {
|
||||||
|
//邮件
|
||||||
|
//SendToChan(to, subject, body, mailtype string) bool
|
||||||
|
subject := fmt.Sprintf("PPGo_Job定时任务异常:%s", j.task.TaskName)
|
||||||
|
body := fmt.Sprintf(
|
||||||
|
`Hello,定时任务出问题了:
|
||||||
|
<p style="font-size:16px;">任务执行详情:</p>
|
||||||
|
<p style="display:block; padding:10px; background:#efefef;border:1px solid #e4e4e4">
|
||||||
|
任务 ID:%d<br/>
|
||||||
|
任务名称:%s<br/>
|
||||||
|
执行时间:%s<br/>
|
||||||
|
执行耗时:%f秒<br/>
|
||||||
|
执行状态:%s
|
||||||
|
</p>
|
||||||
|
<p style="font-size:16px;">任务执行输出</p>
|
||||||
|
<p style="display:block; padding:10px; background:#efefef;border:1px solid #e4e4e4">
|
||||||
|
%s
|
||||||
|
</p>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
<p>-----------------------------------------------------------------<br />
|
||||||
|
本邮件由PPGo_Job定时系统自动发出,请勿回复<br />
|
||||||
|
如果要取消邮件通知,请登录到系统进行设置<br />
|
||||||
|
</p>
|
||||||
|
`, 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)
|
||||||
|
mailtype := "html"
|
||||||
|
|
||||||
|
ok := notify.SendToChan(toEmail, subject, body, mailtype)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("发送邮件错误", toEmail)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if j.task.NotifyType == 1 {
|
||||||
|
//信息
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
j.logId, _ = models.TaskLogAdd(log)
|
j.logId, _ = models.TaskLogAdd(log)
|
||||||
|
|
||||||
// 更新上次执行时间
|
// 更新上次执行时间
|
||||||
@@ -271,3 +357,40 @@ func (j *Job) Run() {
|
|||||||
j.task.ExecuteTimes++
|
j.task.ExecuteTimes++
|
||||||
j.task.Update("PrevTime", "ExecuteTimes")
|
j.task.Update("PrevTime", "ExecuteTimes")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//冗余代码
|
||||||
|
type adminInfo struct {
|
||||||
|
Id int
|
||||||
|
Email string
|
||||||
|
Phone string
|
||||||
|
RealName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func AllAdminInfo(adminIds string) []*adminInfo {
|
||||||
|
Filters := make([]interface{}, 0)
|
||||||
|
Filters = append(Filters, "status", 1)
|
||||||
|
//Filters = append(Filters, "id__gt", 1)
|
||||||
|
var notifyUserIds []int
|
||||||
|
if adminIds != "0" && adminIds != "" {
|
||||||
|
notifyUserIdsStr := strings.Split(adminIds, ",")
|
||||||
|
for _, v := range notifyUserIdsStr {
|
||||||
|
i, _ := strconv.Atoi(v)
|
||||||
|
notifyUserIds = append(notifyUserIds, i)
|
||||||
|
}
|
||||||
|
Filters = append(Filters, "id__in", notifyUserIds)
|
||||||
|
}
|
||||||
|
Result, _ := models.AdminGetList(1, 1000, Filters...)
|
||||||
|
|
||||||
|
adminInfos := make([]*adminInfo, 0)
|
||||||
|
for _, v := range Result {
|
||||||
|
ai := adminInfo{
|
||||||
|
Id: v.Id,
|
||||||
|
Email: v.Email,
|
||||||
|
Phone: v.Phone,
|
||||||
|
RealName: v.RealName,
|
||||||
|
}
|
||||||
|
adminInfos = append(adminInfos, &ai)
|
||||||
|
}
|
||||||
|
|
||||||
|
return adminInfos
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,22 +21,25 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Task struct {
|
type Task struct {
|
||||||
Id int
|
Id int
|
||||||
GroupId int
|
GroupId int
|
||||||
ServerId int
|
ServerId int
|
||||||
TaskName string
|
TaskName string
|
||||||
Description string
|
Description string
|
||||||
CronSpec string
|
CronSpec string
|
||||||
Concurrent int
|
Concurrent int
|
||||||
Command string
|
Command string
|
||||||
Timeout int
|
Timeout int
|
||||||
ExecuteTimes int
|
ExecuteTimes int
|
||||||
PrevTime int64
|
PrevTime int64
|
||||||
Status int
|
Status int
|
||||||
CreateId int
|
IsNotify int
|
||||||
UpdateId int
|
NotifyType int
|
||||||
CreateTime int64
|
NotifyUserIds string
|
||||||
UpdateTime int64
|
CreateId int
|
||||||
|
UpdateId int
|
||||||
|
CreateTime int64
|
||||||
|
UpdateTime int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Task) TableName() string {
|
func (t *Task) TableName() string {
|
||||||
|
|||||||
104
notify/email.go
Normal file
104
notify/email.go
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
/************************************************************
|
||||||
|
** @Description: notify
|
||||||
|
** @Author: george hao
|
||||||
|
** @Date: 2018-08-08 12:59
|
||||||
|
** @Last Modified by: george hao
|
||||||
|
** @Last Modified time: 2018-08-08 12:59
|
||||||
|
*************************************************************/
|
||||||
|
package notify
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/astaxie/beego"
|
||||||
|
"net/smtp"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PEmailConfig struct {
|
||||||
|
Host string
|
||||||
|
Port string
|
||||||
|
User string
|
||||||
|
Pwd string
|
||||||
|
From string
|
||||||
|
}
|
||||||
|
|
||||||
|
type PEmail struct {
|
||||||
|
Config *PEmailConfig
|
||||||
|
Subject string
|
||||||
|
Body string
|
||||||
|
To string
|
||||||
|
Format string
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
mailChan chan *PEmail
|
||||||
|
config *PEmailConfig
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
poolSize, _ := beego.AppConfig.Int("email.pool")
|
||||||
|
host := beego.AppConfig.String("email.host")
|
||||||
|
port := beego.AppConfig.String("email.port")
|
||||||
|
user := beego.AppConfig.String("email.user")
|
||||||
|
pwd := beego.AppConfig.String("email.password")
|
||||||
|
from := beego.AppConfig.String("email.from")
|
||||||
|
|
||||||
|
config = &PEmailConfig{
|
||||||
|
Host: host,
|
||||||
|
From: from,
|
||||||
|
Port: port,
|
||||||
|
User: user,
|
||||||
|
Pwd: pwd,
|
||||||
|
}
|
||||||
|
|
||||||
|
//创建通道
|
||||||
|
mailChan = make(chan *PEmail, poolSize)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case m, ok := <-mailChan:
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := m.SendToEmail(); err != nil {
|
||||||
|
beego.Error("SendMail:", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendToChan(to, subject, body, mailtype string) bool {
|
||||||
|
email := &PEmail{
|
||||||
|
Config: config,
|
||||||
|
Body: body,
|
||||||
|
Subject: subject,
|
||||||
|
Format: mailtype,
|
||||||
|
To: to,
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case mailChan <- email:
|
||||||
|
return true
|
||||||
|
case <-time.After(time.Second * 3):
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pe *PEmail) SendToEmail() error {
|
||||||
|
auth := smtp.PlainAuth("", pe.Config.User, pe.Config.Pwd, pe.Config.Host)
|
||||||
|
var contentType string
|
||||||
|
if pe.Format == "html" {
|
||||||
|
contentType = "Content-Type: text/" + pe.Format + "; charset=UTF-8"
|
||||||
|
} else {
|
||||||
|
contentType = "Content-Type: text/plain" + "; charset=UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := []byte("To: " + pe.To + "\r\nFrom: " + pe.Config.User +
|
||||||
|
"\r\nSubject: " + pe.Subject + "\r\n" + contentType + "\r\n\r\n" + pe.Body)
|
||||||
|
sendTo := strings.Split(pe.To, ";")
|
||||||
|
err := smtp.SendMail(pe.Config.Host+":"+pe.Config.Port, auth, pe.Config.User, sendTo, msg)
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -1,3 +1,8 @@
|
|||||||
|
<style>
|
||||||
|
.notify{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<div class="layui-layout layui-layout-admin" style="padding-left: 40px;margin-top: 20px;">
|
<div class="layui-layout layui-layout-admin" style="padding-left: 40px;margin-top: 20px;">
|
||||||
<form class="layui-form" action="" method="post" >
|
<form class="layui-form" action="" method="post" >
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
@@ -49,8 +54,8 @@
|
|||||||
<label class="layui-form-label mw200">是否单例</label>
|
<label class="layui-form-label mw200">是否单例</label>
|
||||||
<div class="layui-input-inline ">
|
<div class="layui-input-inline ">
|
||||||
|
|
||||||
<input type="radio" name="concurrent" lay-verify="concurrent" value="0" title="是" checked>
|
<input type="radio" name="concurrent" lay-verify="required" value="0" title="是" checked>
|
||||||
<input type="radio" name="concurrent" lay-verify="concurrent" value="1" title="否" >
|
<input type="radio" name="concurrent" lay-verify="required" value="1" title="否" >
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-mid layui-word-aux"><i class="fa fa-info-circle" aria-hidden="true" id="des"></i></div>
|
<div class="layui-form-mid layui-word-aux"><i class="fa fa-info-circle" aria-hidden="true" id="des"></i></div>
|
||||||
@@ -78,6 +83,38 @@
|
|||||||
</div>
|
</div>
|
||||||
<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 mw200">出错通知</label>
|
||||||
|
<div class="layui-input-inline ">
|
||||||
|
<input type="radio" name="is_notify" lay-verify="required" value="1" lay-filter="is_notify" title="是" >
|
||||||
|
<input type="radio" name="is_notify" lay-verify="required" value="0" lay-filter="is_notify" title="否" checked>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-mid layui-word-aux"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item notify">
|
||||||
|
<hr>
|
||||||
|
<label class="layui-form-label mw200">通知类型</label>
|
||||||
|
<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="短信" >
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-mid layui-word-aux"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item notify">
|
||||||
|
<label class="layui-form-label mw200">通知用户</label>
|
||||||
|
<div class="layui-input-inline mw400 ">
|
||||||
|
{{range $k, $v := .adminInfo}}
|
||||||
|
<input type="checkbox" name="notify_user" lay-filter="notify_user" title="{{$v.RealName}}" value="{{$v.Id}}" lay-skin="primary">
|
||||||
|
{{end}}
|
||||||
|
<input type="hidden" name="notify_user_ids" id="notify_user_ids" value="">
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-mid layui-word-aux"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<input type="hidden" name="id" id="id" value="0">
|
<input type="hidden" name="id" id="id" value="0">
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label mw200"></label>
|
<label class="layui-form-label mw200"></label>
|
||||||
@@ -106,6 +143,30 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
var notify_user_ids = [];
|
||||||
|
form.on('checkbox(notify_user)', function(data){
|
||||||
|
if(data.elem.checked==true){
|
||||||
|
notify_user_ids.push(data.value)
|
||||||
|
}else{
|
||||||
|
$.each(notify_user_ids,function(index,item){
|
||||||
|
// index是索引值(即下标) item是每次遍历得到的值;
|
||||||
|
if(item==data.value){
|
||||||
|
notify_user_ids.splice(index,1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$("#notify_user_ids").val(notify_user_ids.join(","));
|
||||||
|
});
|
||||||
|
form.on('radio(is_notify)', function(data){
|
||||||
|
if(data.value==1){
|
||||||
|
$(".notify").show()
|
||||||
|
}else{
|
||||||
|
$(".notify").hide()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
form.on('submit(sub)', function(data){
|
form.on('submit(sub)', function(data){
|
||||||
var form_data = data.field;
|
var form_data = data.field;
|
||||||
$.post('{{urlfor "TaskController.AjaxSave"}}', form_data, function (out) {
|
$.post('{{urlfor "TaskController.AjaxSave"}}', form_data, function (out) {
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
<style>
|
||||||
|
.notify{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<div class="layui-layout layui-layout-admin" style="padding-left: 40px;margin-top: 20px;">
|
<div class="layui-layout layui-layout-admin" style="padding-left: 40px;margin-top: 20px;">
|
||||||
<form class="layui-form" action="" method="post" >
|
<form class="layui-form" action="" method="post" >
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
@@ -79,6 +84,36 @@
|
|||||||
</div>
|
</div>
|
||||||
<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 mw200">出错通知</label>
|
||||||
|
<div class="layui-input-inline ">
|
||||||
|
<input type="radio" name="is_notify" lay-verify="required" value="1" lay-filter="is_notify" title="是" {{if eq .task.IsNotify 1}}checked{{end}}>
|
||||||
|
<input type="radio" name="is_notify" lay-verify="required" value="0" lay-filter="is_notify" title="否" {{if eq .task.IsNotify 0}}checked{{end}}>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-mid layui-word-aux"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item notify">
|
||||||
|
<hr>
|
||||||
|
<label class="layui-form-label mw200">通知类型</label>
|
||||||
|
<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}}>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-mid layui-word-aux"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item notify">
|
||||||
|
<label class="layui-form-label mw200">通知用户</label>
|
||||||
|
<div class="layui-input-inline mw400 ">
|
||||||
|
{{range $k, $v := .adminInfo}}
|
||||||
|
<input type="checkbox" name="notify_user" lay-filter="notify_user" title="{{$v.RealName}}" value="{{$v.Id}}" lay-skin="primary" {{range $ks,$vs:=$.notify_user_ids}} {{if eq $v.Id $vs}}checked{{end}}{{end}}>
|
||||||
|
{{end}}
|
||||||
|
<input type="hidden" name="notify_user_ids" id="notify_user_ids" value="{{.task.NotifyUserIds}}">
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-mid layui-word-aux"></div>
|
||||||
|
</div>
|
||||||
<input type="hidden" name="id" id="id" value="0">
|
<input type="hidden" name="id" id="id" value="0">
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label mw200"></label>
|
<label class="layui-form-label mw200"></label>
|
||||||
@@ -106,6 +141,32 @@
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if ($("input[name=is_notify]:checked").val()==1){
|
||||||
|
$(".notify").show();
|
||||||
|
}
|
||||||
|
form.on('radio(is_notify)', function(data){
|
||||||
|
if(data.value==1){
|
||||||
|
$(".notify").show()
|
||||||
|
}else{
|
||||||
|
$(".notify").hide()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var notify_user_ids = [];
|
||||||
|
form.on('checkbox(notify_user)', function(data){
|
||||||
|
if(data.elem.checked==true){
|
||||||
|
notify_user_ids.push(data.value)
|
||||||
|
}else{
|
||||||
|
$.each(notify_user_ids,function(index,item){
|
||||||
|
// index是索引值(即下标) item是每次遍历得到的值;
|
||||||
|
if(item==data.value){
|
||||||
|
notify_user_ids.splice(index,1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$("#notify_user_ids").val(notify_user_ids.join(","));
|
||||||
|
});
|
||||||
|
|
||||||
form.on('submit(sub)', function(data){
|
form.on('submit(sub)', function(data){
|
||||||
var form_data = data.field;
|
var form_data = data.field;
|
||||||
$.post('{{urlfor "TaskController.AjaxSave"}}', form_data, function (out) {
|
$.post('{{urlfor "TaskController.AjaxSave"}}', form_data, function (out) {
|
||||||
|
|||||||
@@ -90,6 +90,31 @@
|
|||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>出错通知</td>
|
||||||
|
<td>{{if eq .task.IsNotify 0}}否{{end}} {{if eq .task.IsNotify 1}}否{{end}}</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{{if eq .task.IsNotify 1}}
|
||||||
|
<tr>
|
||||||
|
<td>通知类型</td>
|
||||||
|
<td>{{if eq .task.NotifyType 1}}短信{{end}} {{if eq .task.NotifyType 0}}邮件{{end}}</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>通知用户</td>
|
||||||
|
<td>
|
||||||
|
{{range $k, $v := .adminInfo}}
|
||||||
|
{{$v.RealName}}
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{{end}}
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>创建时间</td>
|
<td>创建时间</td>
|
||||||
<td>{{.CreateTime}}</td>
|
<td>{{.CreateTime}}</td>
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
<style>
|
||||||
|
.notify{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<div class="layui-layout layui-layout-admin" style="padding-left: 40px;margin-top: 20px;">
|
<div class="layui-layout layui-layout-admin" style="padding-left: 40px;margin-top: 20px;">
|
||||||
<form class="layui-form" action="javascript:return false;" method="post" >
|
<form class="layui-form" action="javascript:return false;" method="post" >
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
@@ -78,6 +83,36 @@
|
|||||||
</div>
|
</div>
|
||||||
<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 mw200">出错通知</label>
|
||||||
|
<div class="layui-input-inline ">
|
||||||
|
<input type="radio" name="is_notify" lay-verify="required" value="1" lay-filter="is_notify" title="是" {{if eq .task.IsNotify 1}}checked{{end}}>
|
||||||
|
<input type="radio" name="is_notify" lay-verify="required" value="0" lay-filter="is_notify" title="否" {{if eq .task.IsNotify 0}}checked{{end}}>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-mid layui-word-aux"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item notify">
|
||||||
|
<hr>
|
||||||
|
<label class="layui-form-label mw200">通知类型</label>
|
||||||
|
<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}}>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-mid layui-word-aux"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item notify">
|
||||||
|
<label class="layui-form-label mw200">通知用户</label>
|
||||||
|
<div class="layui-input-inline mw400 ">
|
||||||
|
{{range $k, $v := .adminInfo}}
|
||||||
|
<input type="checkbox" name="notify_user" lay-filter="notify_user" title="{{$v.RealName}}" value="{{$v.Id}}" lay-skin="primary" {{range $ks,$vs:=$.notify_user_ids}} {{if eq $v.Id $vs}}checked{{end}}{{end}}>
|
||||||
|
{{end}}
|
||||||
|
<input type="hidden" name="notify_user_ids" id="notify_user_ids" value="{{.task.NotifyUserIds}}">
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-mid layui-word-aux"></div>
|
||||||
|
</div>
|
||||||
<input type="hidden" name="id" id="id" value="{{.task.Id}}">
|
<input type="hidden" name="id" id="id" value="{{.task.Id}}">
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label mw200"></label>
|
<label class="layui-form-label mw200"></label>
|
||||||
@@ -107,6 +142,32 @@
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if ($("input[name=is_notify]:checked").val()==1){
|
||||||
|
$(".notify").show();
|
||||||
|
}
|
||||||
|
form.on('radio(is_notify)', function(data){
|
||||||
|
if(data.value==1){
|
||||||
|
$(".notify").show()
|
||||||
|
}else{
|
||||||
|
$(".notify").hide()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var notify_user_ids = [];
|
||||||
|
form.on('checkbox(notify_user)', function(data){
|
||||||
|
if(data.elem.checked==true){
|
||||||
|
notify_user_ids.push(data.value)
|
||||||
|
}else{
|
||||||
|
$.each(notify_user_ids,function(index,item){
|
||||||
|
// index是索引值(即下标) item是每次遍历得到的值;
|
||||||
|
if(item==data.value){
|
||||||
|
notify_user_ids.splice(index,1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$("#notify_user_ids").val(notify_user_ids.join(","));
|
||||||
|
});
|
||||||
|
|
||||||
form.on('submit(sub)', function(data){
|
form.on('submit(sub)', function(data){
|
||||||
var isAdmin = "{{.isAdmin}}";
|
var isAdmin = "{{.isAdmin}}";
|
||||||
var msg = "编辑任务需要重新审核,是否确认需要编辑?";
|
var msg = "编辑任务需要重新审核,是否确认需要编辑?";
|
||||||
|
|||||||
Reference in New Issue
Block a user