任务列表增加搜索选项

pull/21/merge
ouqiang 8 years ago
parent 1e62bf7f3b
commit 8fbdd7f81e

@ -3,6 +3,7 @@ package models
import (
"time"
"github.com/ouqiang/gocron/modules/ssh"
"github.com/go-xorm/xorm"
)
type TaskProtocol int8
@ -82,7 +83,6 @@ func (task *Task) Enable(id int) (int64, error) {
// 获取所有激活任务
func (task *Task) ActiveList() ([]TaskHost, error) {
task.parsePageAndPageSize()
list := make([]TaskHost, 0)
fields := "t.*, host.alias,host.name,host.username,host.password,host.port,host.auth_type,host.private_key"
err := Db.Alias("t").Join("LEFT", "host", "t.host_id=host.id").Where("t.status = ?", Enabled).Cols(fields).Find(&list)
@ -92,7 +92,6 @@ func (task *Task) ActiveList() ([]TaskHost, error) {
// 获取某个主机下的所有激活任务
func (task *Task) ActiveListByHostId(hostId int16) ([]TaskHost, error) {
task.parsePageAndPageSize()
list := make([]TaskHost, 0)
fields := "t.*, host.alias,host.name,host.username,host.password,host.port,host.auth_type,host.private_key"
err := Db.Alias("t").Join("LEFT", "host", "t.host_id=host.id").Where("t.status = ? AND t.host_id = ?", Enabled, hostId).Cols(fields).Find(&list)
@ -126,11 +125,13 @@ func(task *Task) Detail(id int) (TaskHost, error) {
return taskHost, err
}
func (task *Task) List() ([]TaskHost, error) {
task.parsePageAndPageSize()
func (task *Task) List(params CommonMap) ([]TaskHost, error) {
task.parsePageAndPageSize(params)
list := make([]TaskHost, 0)
fields := "t.*, host.alias"
err := Db.Alias("t").Join("LEFT", "host", "t.host_id=host.id").Cols(fields).Desc("t.id").Limit(task.PageSize, task.pageLimitOffset()).Find(&list)
session := Db.Alias("t").Join("LEFT", "host", "t.host_id=host.id")
parseWhere(session, params)
err := session.Cols(fields).Desc("t.id").Limit(task.PageSize, task.pageLimitOffset()).Find(&list)
return list, err
}
@ -139,7 +140,38 @@ func (task *Task) Total() (int64, error) {
return Db.Count(task)
}
func (task *Task) parsePageAndPageSize() {
// 解析where
func parseWhere(session *xorm.Session, params CommonMap) {
if len(params) == 0 {
return
}
hostId, ok := params["HostId"]
if ok && hostId.(int) > 0 {
session.And("host_id = ? ", hostId)
}
name, ok := params["Name"]
if ok && name.(string) != "" {
session.And("name = ?", name)
}
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)
}
}
func (task *Task) parsePageAndPageSize(params CommonMap) {
page, ok := params["Page"]
if ok {
task.Page = page.(int)
}
pageSize, ok := params["PageSize"]
if ok {
task.PageSize = pageSize.(int)
}
if task.Page <= 0 {
task.Page = Page
}

@ -34,43 +34,43 @@ func Debug(v ...interface{}) {
write(DEBUG, v)
}
func Debugf(format string, v... interface{}) {
writef(DEBUG, format, v)
func Debugf(format string, v ...interface{}) {
writef(DEBUG, format, v...)
}
func Info(v ...interface{}) {
write(INFO, v)
}
func Infof(format string, v... interface{}) {
writef(INFO, format, v)
func Infof(format string, v ...interface{}) {
writef(INFO, format, v...)
}
func Warn(v ...interface{}) {
write(WARN, v)
}
func Warnf(format string, v... interface{}) {
writef(WARN, format, v)
func Warnf(format string, v ...interface{}) {
writef(WARN, format, v...)
}
func Error(v ...interface{}) {
write(ERROR, v)
}
func Errorf(format string, v... interface{}) {
writef(ERROR, format, v)
func Errorf(format string, v ...interface{}) {
writef(ERROR, format, v...)
}
func Fatal(v ...interface{}) {
write(FATAL, v)
}
func Fatalf(format string, v... interface{}) {
writef(FATAL, format, v)
func Fatalf(format string, v ...interface{}) {
writef(FATAL, format, v...)
}
func write(level Level, v... interface{}) {
func write(level Level, v ...interface{}) {
defer logger.Flush()
switch level {
@ -88,21 +88,21 @@ func write(level Level, v... interface{}) {
}
}
func writef(level Level, format string, v... interface{}) {
func writef(level Level, format string, v ...interface{}) {
defer logger.Flush()
switch level {
case DEBUG:
logger.Debugf(format, v)
logger.Debugf(format, v...)
case INFO:
logger.Infof(format, v)
logger.Infof(format, v...)
case WARN:
logger.Warnf(format, v)
logger.Warnf(format, v...)
case FATAL:
logger.Criticalf(format, v)
logger.Criticalf(format, v...)
os.Exit(1)
case ERROR:
logger.Errorf(format, v)
logger.Errorf(format, v...)
}
}

@ -115,7 +115,7 @@ func RegisterMiddleware(m *macaron.Macaron) {
})
// 设置模板共享变量
m.Use(func(ctx *macaron.Context) {
ctx.Data["URI"] = ctx.Req.RequestURI
ctx.Data["URI"] = ctx.Req.URL.Path
})
}

@ -25,27 +25,21 @@ type TaskForm struct {
func Index(ctx *macaron.Context) {
taskModel := new(models.Task)
tasks, err := taskModel.List()
queryParams := parseQueryParams(ctx)
tasks, err := taskModel.List(queryParams)
if err != nil {
logger.Error(err)
}
setHostsToTemplate(ctx)
ctx.Data["Params"] = queryParams
ctx.Data["Title"] = "任务列表"
ctx.Data["Tasks"] = tasks
ctx.HTML(200, "task/index")
}
func Create(ctx *macaron.Context) {
hostModel := new(models.Host)
hosts, err := hostModel.List()
if err != nil || len(hosts) == 0 {
logger.Error(err)
}
setHostsToTemplate(ctx)
ctx.Data["Title"] = "添加任务"
ctx.Data["Hosts"] = hosts
if len(hosts) > 0 {
ctx.Data["FirstHostName"] = hosts[0].Name
ctx.Data["FirstHostId"] = hosts[0].Id
}
ctx.HTML(200, "task/task_form")
}
@ -196,4 +190,32 @@ func addTaskToTimer(id int) {
taskService := service.Task{}
taskService.Add(task)
}
// 解析查询参数
func parseQueryParams(ctx *macaron.Context) (models.CommonMap) {
var params models.CommonMap = models.CommonMap{}
params["HostId"] = ctx.QueryInt("host_id")
params["Name"] = ctx.QueryTrim("name")
params["Protocol"] = ctx.QueryInt("protocol")
params["Status"] = ctx.QueryInt("status")
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()
if err != nil || len(hosts) == 0 {
logger.Error(err)
}
ctx.Data["Hosts"] = hosts
if len(hosts) > 0 {
ctx.Data["FirstHostName"] = hosts[0].Name
ctx.Data["FirstHostId"] = hosts[0].Id
}
}

@ -138,7 +138,7 @@ func (h *HTTPHandler) Run(taskModel models.TaskHost) (result string, err error)
return
}
if resp.StatusCode != 200 {
return string(body), errors.New(fmt.Sprintf("HTTP状态码非200-%d", resp.StatusCode))
return string(body), errors.New(fmt.Sprintf("HTTP状态码非200-->%d", resp.StatusCode))
}
return string(body), err
@ -183,7 +183,7 @@ func createTaskLog(taskModel models.TaskHost) (int64, error) {
func updateTaskLog(taskLogId int64, taskResult TaskResult) (int64, error) {
taskLogModel := new(models.TaskLog)
var status models.Status
var result string
var result string = taskResult.Result
if taskResult.Err != nil {
result = taskResult.Err.Error() + " " + result
status = models.Failure
@ -191,6 +191,7 @@ func updateTaskLog(taskLogId int64, taskResult TaskResult) (int64, error) {
status = models.Finish
}
return taskLogModel.Update(taskLogId, models.CommonMap{
"retry_times": taskResult.RetryTimes,
"status": status,
"result": result,
})
@ -248,7 +249,7 @@ func execJob(handler Handler, taskModel models.TaskHost) TaskResult {
}
i++
if i < execTimes {
logger.Warnf("任务执行失败#任务id-%d#重试第%d次#输出-%s#错误信息-%s", taskModel.Id, i, output, err)
logger.Warnf("任务执行失败#任务id-%d#重试第%d次#输出-%s#错误-%s", taskModel.Id, i, output, err.Error())
}
}

@ -21,7 +21,6 @@
<th>别名</th>
<th>用户名</th>
<th>端口</th>
<th>任务数量</th>
<th>备注</th>
<th>操作</th>
</tr>
@ -33,12 +32,14 @@
<td>{{{.Alias}}}</td>
<td>{{{.Username}}}</td>
<td>{{{.Port}}}</td>
<td></td>
<td>{{{.Remark}}}</td>
<td class="operation">
<a class="ui purple button" href="/host/edit/{{{.Id}}}">编辑</a>
<button class="ui positive button" onclick="util.removeConfirm('/host/remove/{{{.Id}}}')">删除</button>
<button class="ui blue button" @click="ping({{{.Id}}})">连接测试</button>
<button class="ui positive button" onclick="util.removeConfirm('/host/remove/{{{.Id}}}')">删除</button><br>
<div style="margin-top: 5px;">
<a class="ui twitter button" href="/task?host_id={{{.Id}}}">查看任务</a>
<button class="ui blue button" @click="ping({{{.Id}}})">连接测试</button>
</div>
</td>
</tr>
{{{end}}}

@ -13,6 +13,64 @@
</h3>
</div>
</div>
<form class="ui form">
<div class="five fields">
<div class="field">
<input type="text" placeholder="任务名称" name="name">
</div>
<div class="field">
<label>主机</label>
<div class="ui dropdown selection">
<input type="hidden" name="protocol" value="{{{if gt .Params.Protocol 0}}}{{{.Params.Protocol}}}{{{else}}}3{{{end}}}">
<div class="default text">本地命令</div>
<i class="dropdown icon"></i>
<div class="menu">
<div class="item" data-value="3">本地命令</div>
<div class="item" data-value="2">SSH</div>
<div class="item" data-value="1">HTTP</div>
</div>
</div>
<div class="inline fields">
{{{range $i, $v := .Hosts}}}
<div class="field">
<div class="ui radio checkbox">
<input type="radio" name="host_id" tabindex="0" class="hidden" value="{{{.Id}}}"
{{{if eq $.Params.HostId .Id }}} checked {{{end}}}>
</div>
</div>
{{{end}}}
</div>
</div>
<div class="field">
<div class="ui dropdown selection">
<input type="hidden" name="protocol" value="{{{if gt .Params.Protocol 0}}}{{{.Params.Protocol}}}{{{else}}}3{{{end}}}">
<div class="default text">本地命令</div>
<i class="dropdown icon"></i>
<div class="menu">
<div class="item" data-value="-1">协议</div>
<div class="item" data-value="3">本地命令</div>
<div class="item" data-value="2">SSH</div>
<div class="item" data-value="1">HTTP</div>
</div>
</div>
</div>
<div class="field">
<div class="ui dropdown selection">
<input type="hidden" name="status" value="{{{if eq .Params.Status 1}}}1{{{else}}}2{{{end}}}">
<div class="default text">暂停</div>
<i class="dropdown icon"></i>
<div class="menu">
<div class="item" data-value="-1">状态</div>
<div class="item" data-value="2">暂停</div>
<div class="item" data-value="1">激活</div>
</div>
</div>
</div>
<div class="field">
<button class="ui linkedin submit button">搜索</button>
</div>
</div>
</form>
<table class="ui violet table">
<thead>
<tr>
@ -35,7 +93,7 @@
<td>{{{.Spec}}}</td>
<td>{{{if eq .Protocol 1}}} HTTP {{{else}}} SSH {{{end}}}</td>
<td>{{{.Command}}}</td>
<td>{{{.Timeout}}}</td>
<td>{{{if gt .Timeout 0}}}{{{.Timeout}}}秒{{{else}}}不限制{{{end}}}</td>
<td>{{{.RetryTimes}}}</td>
<td>{{{.Alias}}}</td>
<td>{{{.Remark}}}</td>
@ -50,7 +108,7 @@
<button class="ui positive button" @click="remove({{{.Id}}})">删除</button> <br>
<div style="margin-top:10px;">
<button class="ui twitter button" @click="run({{{.Id}}})">手动运行</button>
<button class="ui instagram button">查看日志</button>
<a class="ui instagram button" href="/task/log?task_id={{{.Id}}}">查看日志</a>
</div>
</td>
</tr>

@ -42,7 +42,7 @@
<td>{{{.Name}}}</td>
<td>{{{.Spec}}}</td>
<td>{{{if eq .Protocol 1}}} HTTP {{{else if eq .Protocol 2}}} SSH {{{else}}} 本地命令 {{{end}}}</td>
<td>{{{.Timeout}}}秒</td>
<td>{{{if gt .Timeout 0}}}{{{.Timeout}}}秒{{{else}}}不限制{{{end}}}</td>
<td>{{{.RetryTimes}}}</td>
<td>{{{.Hostname}}}</td>
<td>

@ -73,17 +73,17 @@
<textarea rows="5" name="command">{{{.Task.Command}}}</textarea>
</div>
</div>
<div class="four fields">
<div class="two fields">
<div class="field">
<label>任务超时时间 (单位秒, 默认0不限制超时)</label>
<input type="text" name="timeout" value="{{{.Task.Timeout}}}">
</div>
<div class="field">
<label>任务执行失败重试次数(0-10次, 默认0不重试)</label>
<input type="text" name="retry_times" value="{{{.Task.RetryTimes}}}">
<label>任务执行事变 (单位秒,0不限制,不能超过24小时)</label>
<input type="text" name="timeout" value="{{{.Task.Timeout}}}">
</div>
</div>
<div class="four fields">
<div class="three fields">
<div class="field">
<label>任务状态 (任务添加成功后,是否立即调度)</label>
<div class="ui dropdown selection">

Loading…
Cancel
Save