From 09c6927884ff17ced8701055d97ea37a89226c33 Mon Sep 17 00:00:00 2001 From: ouqiang Date: Sat, 22 Apr 2017 23:39:33 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=BB=E6=9C=BA=E3=80=81=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E5=88=97=E8=A1=A8=E5=A2=9E=E5=8A=A0=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models/host.go | 26 ++++- models/task.go | 12 ++- models/task_log.go | 28 +++++- public/resource/javascript/main.js | 23 ++++- routers/host/host.go | 15 ++- routers/routers.go | 15 ++- routers/task/task.go | 16 ++-- routers/tasklog/task_log.go | 16 +++- service/task.go | 12 +-- templates/common/footer.html | 2 +- templates/common/header.html | 16 +++- templates/host/host_form.html | 46 +++++---- templates/host/index.html | 15 +++ templates/task/index.html | 146 +++++++++++------------------ templates/task/log.html | 78 ++++++--------- templates/task/task_form.html | 75 +++++---------- 16 files changed, 298 insertions(+), 243 deletions(-) diff --git a/models/host.go b/models/host.go index 2f8753b..f16e1b0 100644 --- a/models/host.go +++ b/models/host.go @@ -1,6 +1,9 @@ package models -import "github.com/ouqiang/gocron/modules/ssh" +import ( + "github.com/ouqiang/gocron/modules/ssh" + "github.com/go-xorm/xorm" +) @@ -60,10 +63,12 @@ func (host *Host) NameExists(name string, id int16) (bool, error) { return count > 0, err } -func (host *Host) List() ([]Host, error) { +func (host *Host) List(params CommonMap) ([]Host, error) { host.parsePageAndPageSize() list := make([]Host, 0) - err := Db.Desc("id").Limit(host.PageSize, host.pageLimitOffset()).Find(&list) + session := Db.Desc("id") + host.parseWhere(session, params) + err := session.Limit(host.PageSize, host.pageLimitOffset()).Find(&list) return list, err } @@ -80,6 +85,21 @@ func (host *Host) Total() (int64, error) { return Db.Count(host) } +// 解析where +func (host *Host) parseWhere(session *xorm.Session, params CommonMap) { + if len(params) == 0 { + return + } + id, ok := params["Id"] + if ok && id.(int) > 0 { + session.And("id = ?", id) + } + name, ok := params["Name"] + if ok && name.(string) != "" { + session.And("name = ?", name) + } +} + func (host *Host) parsePageAndPageSize() { if host.Page <= 0 { host.Page = Page diff --git a/models/task.go b/models/task.go index 305e5df..34374ed 100644 --- a/models/task.go +++ b/models/task.go @@ -130,7 +130,7 @@ func (task *Task) List(params CommonMap) ([]TaskHost, error) { list := make([]TaskHost, 0) fields := "t.*, host.alias" session := Db.Alias("t").Join("LEFT", "host", "t.host_id=host.id") - parseWhere(session, params) + task.parseWhere(session, params) err := session.Cols(fields).Desc("t.id").Limit(task.PageSize, task.pageLimitOffset()).Find(&list) return list, err @@ -141,17 +141,21 @@ func (task *Task) Total() (int64, error) { } // 解析where -func parseWhere(session *xorm.Session, params CommonMap) { +func (task *Task) parseWhere(session *xorm.Session, params CommonMap) { if len(params) == 0 { return } + id, ok := params["Id"] + if ok && id.(int) > 0 { + session.And("t.id = ?", id) + } hostId, ok := params["HostId"] if ok && hostId.(int) > 0 { - session.And("host_id = ? ", hostId) + session.And("host_id = ?", hostId) } name, ok := params["Name"] if ok && name.(string) != "" { - session.And("name = ?", name) + session.And("t.name LIKE ?", "%" + name.(string) + "%") } protocol, ok := params["Protocol"] if ok && protocol.(int) > 0 { diff --git a/models/task_log.go b/models/task_log.go index 2d4ea54..2f9ae65 100644 --- a/models/task_log.go +++ b/models/task_log.go @@ -2,6 +2,7 @@ package models import ( "time" + "github.com/go-xorm/xorm" ) type TaskType int8 @@ -20,7 +21,7 @@ type TaskLog struct { Hostname string `xorm:"varchar(512) notnull defalut '' "` // SSH主机名,逗号分隔 StartTime time.Time `xorm:"datetime created"` // 开始执行时间 EndTime time.Time `xorm:"datetime updated"` // 执行完成(失败)时间 - Status Status `xorm:"tinyint notnull default 1"` // 状态 1:执行中 2:执行完毕 0:执行失败 + Status Status `xorm:"tinyint notnull default 1"` // 状态 0:执行失败 1:执行中 2:执行完毕 Result string `xorm:"varchar(65535) notnull defalut '' "` // 执行结果 Page int `xorm:"-"` PageSize int `xorm:"-"` @@ -47,10 +48,12 @@ func (taskLog *TaskLog) setStatus(id int64, status Status) (int64, error) { return taskLog.Update(id, CommonMap{"status": status}) } -func (taskLog *TaskLog) List() ([]TaskLog, error) { +func (taskLog *TaskLog) List(params CommonMap) ([]TaskLog, error) { taskLog.parsePageAndPageSize() list := make([]TaskLog, 0) - err := Db.Desc("id").Limit(taskLog.PageSize, taskLog.pageLimitOffset()).Find(&list) + session := Db.Desc("id") + taskLog.parseWhere(session, params) + err := session.Limit(taskLog.PageSize, taskLog.pageLimitOffset()).Find(&list) if len(list) > 0 { for i, item := range list { endTime := item.EndTime @@ -85,4 +88,23 @@ func (taskLog *TaskLog) parsePageAndPageSize() { func (taskLog *TaskLog) pageLimitOffset() int { return (taskLog.Page - 1) * taskLog.PageSize +} + +// 解析where +func (taskLog *TaskLog) parseWhere(session *xorm.Session, params CommonMap) { + if len(params) == 0 { + return + } + taskId, ok := params["TaskId"] + if ok && taskId.(int) > 0 { + session.And("task_id = ?", taskId) + } + protocol, ok := params["Protocol"] + if ok && protocol.(int) > 0 { + session.And("protocol = ?", protocol) + } + status, ok := params["Status"] + if ok && status.(int) > -1 { + session.And("status = ?", status) + } } \ No newline at end of file diff --git a/public/resource/javascript/main.js b/public/resource/javascript/main.js index 6a1a721..6ba72de 100644 --- a/public/resource/javascript/main.js +++ b/public/resource/javascript/main.js @@ -24,8 +24,6 @@ function Util() { swal(FAILURE_MESSAGE, '未知错误', 'error'); }; util.get = function(url, callback) { - var SUCCESS = 0; // 操作成功 - var FAILURE_MESSAGE = '操作失败'; $.get( url, function(response) { @@ -76,4 +74,25 @@ function Util() { return util; } +function registerSelectFormValidation(type, $form, $select, selectName) { + $.fn.form.settings.rules[type] = function(value) { + var success = true; + var selectedIndex = $($form).form("get value", selectName); + $($select).find("option").each(function() { + var value = $(this).val(); + var match = $(this).data("match"); + var validateType = $(this).data("validate-type"); + if (selectedIndex == value && validateType == type && match) { + var matchValue = $($form).form("get value", match); + if (!$.trim(matchValue)) { + success = false; + return false; + } + } + }); + + return success; + }; +} + var util = new Util(); \ No newline at end of file diff --git a/routers/host/host.go b/routers/host/host.go index bad2f82..517d43e 100644 --- a/routers/host/host.go +++ b/routers/host/host.go @@ -12,12 +12,14 @@ import ( func Index(ctx *macaron.Context) { hostModel := new(models.Host) - hosts, err := hostModel.List() + queryParams := parseQueryParams(ctx) + hosts, err := hostModel.List(queryParams) if err != nil { logger.Error(err) } ctx.Data["Title"] = "主机列表" ctx.Data["Hosts"] = hosts + ctx.Data["Params"] = queryParams ctx.HTML(200, "host/index") } @@ -142,4 +144,15 @@ func Remove(ctx *macaron.Context) string { } return json.Success("操作成功", nil) +} + +// 解析查询参数 +func parseQueryParams(ctx *macaron.Context) (models.CommonMap) { + var params models.CommonMap = models.CommonMap{} + params["Id"] = ctx.QueryInt("id") + params["Name"] = ctx.QueryTrim("name") + params["Page"] = ctx.QueryInt("page") + params["PageSize"] = ctx.QueryInt("page_size") + + return params } \ No newline at end of file diff --git a/routers/routers.go b/routers/routers.go index 210c70d..b6cb8b6 100644 --- a/routers/routers.go +++ b/routers/routers.go @@ -11,7 +11,6 @@ import ( "github.com/go-macaron/session" "github.com/go-macaron/csrf" "github.com/go-macaron/toolbox" - "github.com/go-macaron/gzip" "strings" "github.com/ouqiang/gocron/modules/app" ) @@ -35,6 +34,7 @@ func Register(m *macaron.Macaron) { }) // 50x错误 m.InternalServerError(func(ctx *macaron.Context) { + logger.Debug("500错误") if isGetRequest(ctx) && !isAjaxRequest(ctx) { ctx.Data["Title"] = "500 - INTERNAL SERVER ERROR" ctx.HTML(500, "error/500") @@ -85,7 +85,6 @@ func Register(m *macaron.Macaron) { func RegisterMiddleware(m *macaron.Macaron) { m.Use(macaron.Logger()) m.Use(macaron.Recovery()) - m.Use(gzip.Gziper()) m.Use(macaron.Static(StaticDir)) m.Use(macaron.Renderer(macaron.RenderOptions{ Directory: "templates", @@ -106,7 +105,7 @@ func RegisterMiddleware(m *macaron.Macaron) { // 系统未安装,重定向到安装页面 m.Use(func(ctx *macaron.Context) { installUrl := "/install" - if strings.HasPrefix(ctx.Req.RequestURI, installUrl) { + if strings.HasPrefix(ctx.Req.URL.Path, installUrl) { return } if !app.Installed { @@ -116,6 +115,16 @@ func RegisterMiddleware(m *macaron.Macaron) { // 设置模板共享变量 m.Use(func(ctx *macaron.Context) { ctx.Data["URI"] = ctx.Req.URL.Path + urlPath := strings.TrimPrefix(ctx.Req.URL.Path, "/") + paths := strings.Split(urlPath, "/") + ctx.Data["Controller"] = "" + ctx.Data["Action"] = "" + if len(paths) > 0 { + ctx.Data["Controller"] = paths[0] + } + if len(paths) > 1 { + ctx.Data["Action"] = paths[1] + } }) } diff --git a/routers/task/task.go b/routers/task/task.go index 0eb06f2..eba19b1 100644 --- a/routers/task/task.go +++ b/routers/task/task.go @@ -46,7 +46,7 @@ func Create(ctx *macaron.Context) { func Edit(ctx *macaron.Context) { id := ctx.ParamsInt(":id") hostModel := new(models.Host) - hosts, err := hostModel.List() + hosts, err := hostModel.List(models.CommonMap{}) if err != nil || len(hosts) == 0 { logger.Error(err) } @@ -87,11 +87,16 @@ func Store(ctx *macaron.Context, form TaskForm) string { return json.CommonFailure("请选择主机名") } + if form.Protocol != models.TaskHTTP { + taskModel.HostId = form.HostId + } else { + taskModel.HostId = 0 + } + taskModel.Name = form.Name taskModel.Protocol = form.Protocol taskModel.Command = form.Command taskModel.Timeout = form.Timeout - taskModel.HostId = form.HostId taskModel.Remark = form.Remark taskModel.Status = form.Status taskModel.RetryTimes = form.RetryTimes @@ -195,21 +200,20 @@ func addTaskToTimer(id int) { // 解析查询参数 func parseQueryParams(ctx *macaron.Context) (models.CommonMap) { var params models.CommonMap = models.CommonMap{} + params["Id"] = ctx.QueryInt("id") params["HostId"] = ctx.QueryInt("host_id") params["Name"] = ctx.QueryTrim("name") params["Protocol"] = ctx.QueryInt("protocol") - params["Status"] = ctx.QueryInt("status") + params["Status"] = ctx.QueryInt("status") - 1 params["Page"] = ctx.QueryInt("page") params["PageSize"] = ctx.QueryInt("page_size") - logger.Debug("%+v", params) - return params } func setHostsToTemplate(ctx *macaron.Context) { hostModel := new(models.Host) - hosts, err := hostModel.List() + hosts, err := hostModel.List(models.CommonMap{}) if err != nil || len(hosts) == 0 { logger.Error(err) } diff --git a/routers/tasklog/task_log.go b/routers/tasklog/task_log.go index ac1fb4d..da32710 100644 --- a/routers/tasklog/task_log.go +++ b/routers/tasklog/task_log.go @@ -12,12 +12,14 @@ import ( func Index(ctx *macaron.Context) { logModel := new(models.TaskLog) - logs, err := logModel.List() + queryParams := parseQueryParams(ctx) + logs, err := logModel.List(queryParams) if err != nil { logger.Error(err) } ctx.Data["Title"] = "任务日志" ctx.Data["Logs"] = logs + ctx.Data["Params"] = queryParams ctx.HTML(200, "task/log") } @@ -31,4 +33,16 @@ func Clear(ctx *macaron.Context) string { } return json.Success(utils.SuccessContent, nil) +} + +// 解析查询参数 +func parseQueryParams(ctx *macaron.Context) (models.CommonMap) { + var params models.CommonMap = models.CommonMap{} + params["TaskId"] = ctx.QueryInt("task_id") + params["Protocol"] = ctx.QueryInt("protocol") + params["Status"] = ctx.QueryInt("status") - 1 + params["Page"] = ctx.QueryInt("page") + params["PageSize"] = ctx.QueryInt("page_size") + + return params } \ No newline at end of file diff --git a/service/task.go b/service/task.go index 1abb7c4..17070f8 100644 --- a/service/task.go +++ b/service/task.go @@ -57,6 +57,7 @@ func (task *Task) Add(taskModel models.TaskHost) { } cronName := strconv.Itoa(taskModel.Id) + // Cron任务采用数组存储, 删除任务需遍历数组, 并对数组重新赋值, 任务较多时,有性能问题 Cron.RemoveJob(cronName) err := Cron.AddFunc(taskModel.Spec, taskFunc, cronName) if err != nil { @@ -123,20 +124,17 @@ func (h *HTTPHandler) Run(taskModel models.TaskHost) (result string, err error) req.Header.Set("User-Agent", "golang/gocron") resp, err := client.Do(req) - defer func() { - if resp != nil { - resp.Body.Close() - } - }() if err != nil { logger.Error("任务处理HTTP请求错误-", err.Error()) return } + defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { logger.Error("任务处理#读取HTTP请求返回值失败-", err.Error()) return } + // 返回状态码非200,均为失败 if resp.StatusCode != 200 { return string(body), errors.New(fmt.Sprintf("HTTP状态码非200-->%d", resp.StatusCode)) } @@ -248,10 +246,10 @@ func execJob(handler Handler, taskModel models.TaskHost) TaskResult { return TaskResult{Result: output, Err: err, RetryTimes: i} } i++ - // 重试规则,每次递增1分钟 - time.Sleep( time.Duration(i) * 60 * time.Second) if i < execTimes { logger.Warnf("任务执行失败#任务id-%d#重试第%d次#输出-%s#错误-%s", taskModel.Id, i, output, err.Error()) + // 重试间隔时间,每次递增1分钟 + time.Sleep( time.Duration(i) * time.Minute) } } diff --git a/templates/common/footer.html b/templates/common/footer.html index 6ac44b8..ac93109 100644 --- a/templates/common/footer.html +++ b/templates/common/footer.html @@ -5,7 +5,7 @@

© 2017 gocron - + GitHub

diff --git a/templates/common/header.html b/templates/common/header.html index 9d1ce37..0c66ffd 100644 --- a/templates/common/header.html +++ b/templates/common/header.html @@ -18,6 +18,12 @@ body { overflow-x: hidden; } + select { + height: 40px; + } + .fields.search > .field { + margin-right: 5px; + } @@ -53,11 +59,11 @@ \ No newline at end of file diff --git a/templates/host/host_form.html b/templates/host/host_form.html index 0fef7e0..5f46f3b 100644 --- a/templates/host/host_form.html +++ b/templates/host/host_form.html @@ -1,7 +1,6 @@ {{{ template "common/header" . }}}
- {{{ template "host/menu" . }}}
@@ -48,19 +47,10 @@
- +
@@ -91,12 +81,14 @@
保存
-
-{{{ template "common/footer" . }}} \ No newline at end of file +{{{ template "common/footer" . }}} diff --git a/templates/task/log.html b/templates/task/log.html index 4850430..d128087 100644 --- a/templates/task/log.html +++ b/templates/task/log.html @@ -22,9 +22,36 @@
+
+ +
+ @@ -39,6 +66,7 @@ {{{range $i, $v := .Logs}}} + @@ -128,55 +156,5 @@ }); }); } - - $('.ui.form').form( - { - onSuccess: function(event, fields) { - util.post('/host/store', fields, function(code, message) { - location.reload(); - }); - - return false; - }, - fields: { - name: { - identifier : 'name', - rules: [ - { - type : 'empty', - prompt : '请输入主机名' - } - ] - }, - alias: { - identifier : 'alias', - rules: [ - { - type : 'empty', - prompt : '请输入主机别名' - } - ] - }, - username: { - identifier : 'username', - rules: [ - { - type : 'empty', - prompt : '请输入SSH用户名' - } - ] - }, - port: { - identifier : 'port', - rules: [ - { - type : 'integer', - prompt : '请输入SSH端口' - } - ] - } - }, - inline : true - }); {{{ template "common/footer" . }}} \ No newline at end of file diff --git a/templates/task/task_form.html b/templates/task/task_form.html index ad58d52..e9e41c2 100644 --- a/templates/task/task_form.html +++ b/templates/task/task_form.html @@ -1,5 +1,4 @@ {{{ template "common/header" . }}} -
{{{template "task/menu" .}}}
@@ -25,47 +24,31 @@
- - + +
+ +
- +
-
+ - {{{else}}} - - {{{end}}} - -
+
{{{end}}} -
+
@@ -73,32 +56,23 @@
-
+
- +
- +
@@ -117,7 +91,9 @@ $('.ui.checkbox') .checkbox() ; - $('.ui.form').form( + var $uiForm = $('.ui.form'); + registerSelectFormValidation("selectProtocol", $uiForm, $('#protocol'), 'protocol'); + $($uiForm).form( { onSuccess: function(event, fields) { util.post('/task/store', fields, function(code, message) { @@ -153,11 +129,12 @@ prompt : '请输入任务命令' } ] - }, hosts: { - identifier : 'hosts', + }, + hosts: { + identifier : 'host_id', rules: [ { - type : 'checked', + type : 'selectProtocol', prompt : '请选择主机' } ]
任务ID 任务名称 cron表达式 协议
{{{.TaskId}}} {{{.Name}}} {{{.Spec}}} {{{if eq .Protocol 1}}} HTTP {{{else if eq .Protocol 2}}} SSH {{{else}}} 本地命令 {{{end}}}