优化首页内容
This commit is contained in:
30
README.md
30
README.md
@@ -1,12 +1,15 @@
|
|||||||
PPGo_Job定时任务管理系统 V2.x
|
PPGo_Job定时任务管理系统
|
||||||
====
|
====
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
PPGo_Job是一款定时任务可视化的、多人多权限的管理系统,采用golang开发,安装方便,资源消耗少,支持大并发,可同时管理多台服务器上的定时任务。
|
##说明
|
||||||
|
PPGo_Job是一款轻量级定时任务管理系统,go语言开发,部署超级简单,资源消耗少,运行稳定。
|
||||||
|
支持定时任务可视化管理、多人多权限的管理,支持大并发,可同时管理多台服务器上的定时任务。
|
||||||
|
|
||||||
|
PPGo_Job从v1.0开源以来,得到众多技术朋友的支持和欢迎,已应用在多个公司的生产环境,同时也
|
||||||
|
吸收使用者的建议和意见,不断改进和优化,目前已经上线了20余个版本,9个稳定版本(生产环境部署完成后才发布新版本)。
|
||||||
|
|
||||||
前言:PPGo_Job V1.x版本开源两年多了,不少朋友的公司都在用,反响还不错,当然,也有好多朋友提了不少合理的意见和建议,所以这次干脆重构了一下,连UI也重新编码。目前V2.x版本
|
|
||||||
已经用于生产环境。
|
|
||||||
|
|
||||||
码云地址:https://gitee.com/georgehao/PPGo_Job
|
码云地址:https://gitee.com/georgehao/PPGo_Job
|
||||||
Github地址:https://github.com/george518/PPGo_Job
|
Github地址:https://github.com/george518/PPGo_Job
|
||||||
@@ -14,11 +17,15 @@ Github地址:https://github.com/george518/PPGo_Job
|
|||||||
文档地址:http://www.haodaquan.com/topics/1###
|
文档地址:http://www.haodaquan.com/topics/1###
|
||||||
Wiki:https://github.com/george518/PPGo_Job/wiki
|
Wiki:https://github.com/george518/PPGo_Job/wiki
|
||||||
|
|
||||||
|
##架构
|
||||||
|
|
||||||
V1.x版本是一个简单的定时任务管理系统,进入V1.0 :https://github.com/george518/PPGo_Job/releases/tag/v1.2.1
|

|
||||||
相对于V1.x版本,V2.0新增以下功能和特性:
|
|
||||||
|
|
||||||
- 1、全新UI,基于LayUI2.3构建全新页面,后端模板手工搭建,让操作更加人性化。后台模板地址:https://github.com/george518/PP_admin-template
|
##特性
|
||||||
|
|
||||||
|
V2.x新增以下功能和特性:
|
||||||
|
|
||||||
|
- 1、全新UI,基于LayUI构建全新页面,后端模板手工搭建,让操作更加人性化。后台模板地址:https://github.com/george518/PP_admin-template
|
||||||
- 2、新增权限管理功能,根据菜单权限、操作权限和数据权限进行划分,方便多用户多权限管理定时任务。
|
- 2、新增权限管理功能,根据菜单权限、操作权限和数据权限进行划分,方便多用户多权限管理定时任务。
|
||||||
- 3、新增服务器复制功能,让服务器资源添加更加方便。
|
- 3、新增服务器复制功能,让服务器资源添加更加方便。
|
||||||
- 4、新增定时任务详情页面,将任务相关操作更加集中起来操作。
|
- 4、新增定时任务详情页面,将任务相关操作更加集中起来操作。
|
||||||
@@ -29,13 +36,16 @@ V1.x版本是一个简单的定时任务管理系统,进入V1.0 :https://git
|
|||||||
- 9、支持windows系统运行定时系统,不歧视windows,也要支持。
|
- 9、支持windows系统运行定时系统,不歧视windows,也要支持。
|
||||||
- 10、提醒信息新增钉钉和微信通知功能,并支持编辑通知模版功能。让提醒内容个性化,不再死板。
|
- 10、提醒信息新增钉钉和微信通知功能,并支持编辑通知模版功能。让提醒内容个性化,不再死板。
|
||||||
- 11、新增创建、启动、关闭任务的API,通过接口的方式控制定时任务,猜你喜欢。
|
- 11、新增创建、启动、关闭任务的API,通过接口的方式控制定时任务,猜你喜欢。
|
||||||
|
- 12、**新增任务执行器agent,可以通过ssh,telnet或者agent的方式分发任务**
|
||||||
|
|
||||||
总之,管理定时任务,使用PPGo_Job吧,节省出来的时间,或皮或浪,随你,哈哈。
|
总之,管理定时任务,使用PPGo_Job吧,节省出来的时间,或皮或浪,随你。
|
||||||
|
|
||||||
感觉不错的话,给个星星吧 :)
|
|
||||||
|
|
||||||
也可以请我喝水
|
|
||||||
|
##支持
|
||||||
----
|
----
|
||||||
|
####1、给项目一个star
|
||||||
|
####2、请我喝瓶水
|
||||||

|

|
||||||
|
|
||||||
先看效果
|
先看效果
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
//任务执行器
|
|
||||||
//
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
}
|
|
||||||
BIN
agent/agent
Executable file
BIN
agent/agent
Executable file
Binary file not shown.
@@ -6,19 +6,18 @@ Version = 1.0.0
|
|||||||
LogLevel = ALL
|
LogLevel = ALL
|
||||||
# 执行器配置
|
# 执行器配置
|
||||||
# auto-自动起名,或者自己起名
|
# auto-自动起名,或者自己起名
|
||||||
ServerName = agent-10.32.40.165-1564
|
ServerName = agent-192.168.1.101-1564
|
||||||
# 启动后回写
|
# 启动后回写
|
||||||
ServerId = 7
|
ServerId = 4
|
||||||
# 端口,必须配置!!
|
# 端口,必须配置!!
|
||||||
TcpPort = 1564
|
TcpPort = 1564
|
||||||
# auto-自动获取
|
# auto-自动获取
|
||||||
TcpIp = 10.32.40.165
|
TcpIp = 192.168.1.101
|
||||||
# Ip地址是外网还是内网,1-外网,0-内网,若填写TcpIp则本项配置无意义
|
# Ip地址是外网还是内网,1-外网,0-内网,若填写TcpIp则本项配置无意义
|
||||||
IpType = 0
|
IpType = 0
|
||||||
# 添加的执行器属于分组Id,默认为1
|
# 添加的执行器属于分组Id,默认为1
|
||||||
GroupId = 1
|
GroupId = 1
|
||||||
|
|
||||||
# 以下配置必填,地址格式:http://yourdomain/server/apisave
|
# 以下配置必填,地址格式:http://yourdomain/server/apisave
|
||||||
RegisterUrl = http://localhost:8081/server/apisave
|
RegisterUrl = http://localhost:8080/server/apisave
|
||||||
UpdateStatusUrl = http://localhost:8081/server/apistatus
|
UpdateStatusUrl = http://localhost:8080/server/apistatus
|
||||||
|
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ func ResetCommandJob(id int, serverId int, name string, command string) *Job {
|
|||||||
err, isTimeout := runCmdWithTimeout(cmd, timeout)
|
err, isTimeout := runCmdWithTimeout(cmd, timeout)
|
||||||
|
|
||||||
jobResult = new(JobResult)
|
jobResult = new(JobResult)
|
||||||
jobResult.ErrMsg = libs.GbkAsUtf8(bufErr.String())
|
jobResult.ErrMsg = bufErr.String()
|
||||||
jobResult.OutMsg = libs.GbkAsUtf8(bufOut.String())
|
jobResult.OutMsg = bufOut.String()
|
||||||
jobResult.IsOk = true
|
jobResult.IsOk = true
|
||||||
if err != nil {
|
if err != nil {
|
||||||
jobResult.IsOk = false
|
jobResult.IsOk = false
|
||||||
|
|||||||
15
agent/test/sqls/ts.go
Normal file
15
agent/test/sqls/ts.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/************************************************************
|
||||||
|
** @Description: ts
|
||||||
|
** @Author: george hao
|
||||||
|
** @Date: 2019-07-04 17:23
|
||||||
|
** @Last Modified by: george hao
|
||||||
|
** @Last Modified time: 2019-07-04 17:23
|
||||||
|
*************************************************************/
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/george518/PPGo_Job/models"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
models.TaskTotalRunNum()
|
||||||
|
}
|
||||||
BIN
assets/screenshot/ppgo.png
Normal file
BIN
assets/screenshot/ppgo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 120 KiB |
@@ -1,9 +1,9 @@
|
|||||||
AppName = PPGo_Job2
|
AppName = PPGo_Job2
|
||||||
HTTPPort = 8081
|
HTTPPort = 8080
|
||||||
RunMode = dev
|
RunMode = dev
|
||||||
SessionOn = true
|
SessionOn = true
|
||||||
|
|
||||||
version= V2.7
|
version= V2.8
|
||||||
|
|
||||||
# 允许同时运行的任务数
|
# 允许同时运行的任务数
|
||||||
jobs.pool = 1000
|
jobs.pool = 1000
|
||||||
@@ -19,7 +19,7 @@ db.host = 127.0.0.1
|
|||||||
db.user = root
|
db.user = root
|
||||||
db.password = "123456"
|
db.password = "123456"
|
||||||
db.port = 3306
|
db.port = 3306
|
||||||
db.name = cron
|
db.name = ppgo_job3
|
||||||
db.prefix = pp_
|
db.prefix = pp_
|
||||||
db.timezone = Asia/Shanghai
|
db.timezone = Asia/Shanghai
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ import (
|
|||||||
"github.com/george518/PPGo_Job/libs"
|
"github.com/george518/PPGo_Job/libs"
|
||||||
"github.com/george518/PPGo_Job/models"
|
"github.com/george518/PPGo_Job/models"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
//"strconv"
|
//"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -34,9 +37,47 @@ func (self *HomeController) Help() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *HomeController) Start() {
|
func (self *HomeController) Start() {
|
||||||
|
|
||||||
|
//总任务数量
|
||||||
|
_, count := models.TaskGetList(1, 10)
|
||||||
|
self.Data["totalJob"] = count
|
||||||
|
|
||||||
|
//日志总量
|
||||||
|
_, totalLog := models.TaskLogGetList(1, 10)
|
||||||
|
self.Data["totalLog"] = totalLog
|
||||||
|
|
||||||
|
//待审核任务数量
|
||||||
|
_, totalAuditTask := models.TaskGetList(1, 10, "status", 2)
|
||||||
|
self.Data["totalAuditTask"] = totalAuditTask
|
||||||
|
|
||||||
|
//失败
|
||||||
|
errorNum, err := models.GetLogNum(-1)
|
||||||
|
if err != nil {
|
||||||
|
errorNum = 0
|
||||||
|
}
|
||||||
|
self.Data["errorNum"] = errorNum
|
||||||
|
|
||||||
|
//成功
|
||||||
|
successNum, err := models.GetLogNum(0)
|
||||||
|
if err != nil {
|
||||||
|
successNum = 0
|
||||||
|
}
|
||||||
|
self.Data["successNum"] = successNum
|
||||||
|
|
||||||
|
//用户数
|
||||||
|
_, userNum := models.AdminGetList(1, 10, "status", 1)
|
||||||
|
self.Data["userNum"] = userNum
|
||||||
|
|
||||||
|
//累计运行总次数
|
||||||
|
n, err := models.TaskTotalRunNum()
|
||||||
|
if err != nil {
|
||||||
|
n = 0
|
||||||
|
}
|
||||||
|
self.Data["TaskTotalRunNum"] = n
|
||||||
|
|
||||||
groups_map := serverGroupLists(self.serverGroups, self.userId)
|
groups_map := serverGroupLists(self.serverGroups, self.userId)
|
||||||
//计算总任务数量
|
//计算总任务数量
|
||||||
_, count := models.TaskGetList(1, 300)
|
|
||||||
// 即将执行的任务
|
// 即将执行的任务
|
||||||
entries := jobs.GetEntries(30)
|
entries := jobs.GetEntries(30)
|
||||||
jobList := make([]map[string]interface{}, len(entries))
|
jobList := make([]map[string]interface{}, len(entries))
|
||||||
@@ -53,35 +94,10 @@ func (self *HomeController) Start() {
|
|||||||
startJob++
|
startJob++
|
||||||
}
|
}
|
||||||
|
|
||||||
// 最近执行的日志
|
self.Data["recentLogs"] = jobList
|
||||||
logs, _ := models.TaskLogGetList(1, 20)
|
|
||||||
recentLogs := make([]map[string]interface{}, len(logs))
|
|
||||||
failJob := 0 //最近失败的数量
|
|
||||||
okJob := 0 //最近成功的数量
|
|
||||||
for k, v := range logs {
|
|
||||||
task, err := models.TaskGetById(v.TaskId)
|
|
||||||
taskName := ""
|
|
||||||
if err == nil {
|
|
||||||
taskName = task.TaskName
|
|
||||||
}
|
|
||||||
row := make(map[string]interface{})
|
|
||||||
row["task_name"] = taskName
|
|
||||||
row["id"] = v.Id
|
|
||||||
row["start_time"] = beego.Date(time.Unix(v.CreateTime, 0), "Y-m-d H:i:s")
|
|
||||||
row["process_time"] = float64(v.ProcessTime) / 1000
|
|
||||||
row["ouput_size"] = libs.SizeFormat(float64(len(v.Output)))
|
|
||||||
row["output"] = beego.Substr(v.Output, 0, 100)
|
|
||||||
row["status"] = v.Status
|
|
||||||
recentLogs[k] = row
|
|
||||||
if v.Status != 0 {
|
|
||||||
failJob++
|
|
||||||
} else {
|
|
||||||
okJob++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 最近执行失败的日志
|
// 最近执行失败的日志
|
||||||
logs, _ = models.TaskLogGetList(1, 20, "status__lt", 0)
|
logs, _ := models.TaskLogGetList(1, 30, "status__lt", 0)
|
||||||
errLogs := make([]map[string]interface{}, len(logs))
|
errLogs := make([]map[string]interface{}, len(logs))
|
||||||
|
|
||||||
for k, v := range logs {
|
for k, v := range logs {
|
||||||
@@ -102,15 +118,61 @@ func (self *HomeController) Start() {
|
|||||||
errLogs[k] = row
|
errLogs[k] = row
|
||||||
|
|
||||||
}
|
}
|
||||||
|
self.Data["errLogs"] = errLogs
|
||||||
self.Data["startJob"] = startJob
|
self.Data["startJob"] = startJob
|
||||||
self.Data["okJob"] = okJob
|
|
||||||
self.Data["failJob"] = failJob
|
|
||||||
self.Data["totalJob"] = count
|
|
||||||
|
|
||||||
self.Data["recentLogs"] = recentLogs
|
|
||||||
// this.Data["errLogs"] = errLogs
|
|
||||||
self.Data["jobs"] = jobList
|
self.Data["jobs"] = jobList
|
||||||
|
|
||||||
|
//折线图
|
||||||
|
okRun := models.SumByDays(30, "0")
|
||||||
|
errRun := models.SumByDays(30, "-1")
|
||||||
|
expiredRun := models.SumByDays(30, "-2")
|
||||||
|
|
||||||
|
days := []string{}
|
||||||
|
okNum := []int64{}
|
||||||
|
errNum := []int64{}
|
||||||
|
expiredNum := []int64{}
|
||||||
|
|
||||||
|
type kv struct {
|
||||||
|
Key string
|
||||||
|
Value int64
|
||||||
|
}
|
||||||
|
|
||||||
|
//排序
|
||||||
|
var ss []kv
|
||||||
|
for k, v := range okRun {
|
||||||
|
i, _ := strconv.ParseInt(v.(string), 10, 64)
|
||||||
|
ss = append(ss, kv{k, i})
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(ss, func(i, j int) bool {
|
||||||
|
|
||||||
|
return ss[i].Key < ss[j].Key
|
||||||
|
})
|
||||||
|
|
||||||
|
for _, v := range ss {
|
||||||
|
|
||||||
|
days = append(days, v.Key)
|
||||||
|
okNum = append(okNum, v.Value)
|
||||||
|
|
||||||
|
if _, ok := errRun[v.Key]; ok {
|
||||||
|
i, _ := strconv.ParseInt(errRun[v.Key].(string), 10, 64)
|
||||||
|
errNum = append(errNum, i)
|
||||||
|
} else {
|
||||||
|
errNum = append(errNum, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := expiredRun[v.Key]; ok {
|
||||||
|
i, _ := strconv.ParseInt(expiredRun[v.Key].(string), 10, 64)
|
||||||
|
expiredNum = append(expiredNum, i)
|
||||||
|
} else {
|
||||||
|
expiredNum = append(expiredNum, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.Data["days"] = days
|
||||||
|
self.Data["okNum"] = okNum
|
||||||
|
self.Data["errNum"] = errNum
|
||||||
|
self.Data["expiredNum"] = expiredNum
|
||||||
self.Data["cpuNum"] = runtime.NumCPU()
|
self.Data["cpuNum"] = runtime.NumCPU()
|
||||||
|
|
||||||
//系统运行信息
|
//系统运行信息
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
@@ -53,6 +55,7 @@ func (self *ServerGroupController) AjaxSave() {
|
|||||||
|
|
||||||
servergroup_id, _ := self.GetInt("id")
|
servergroup_id, _ := self.GetInt("id")
|
||||||
|
|
||||||
|
fmt.Println(servergroup_id)
|
||||||
if servergroup_id == 0 {
|
if servergroup_id == 0 {
|
||||||
//新增
|
//新增
|
||||||
servergroup.CreateTime = time.Now().Unix()
|
servergroup.CreateTime = time.Now().Unix()
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ func (self *TaskController) Detail() {
|
|||||||
//任务分组
|
//任务分组
|
||||||
groupName := "默认分组"
|
groupName := "默认分组"
|
||||||
if task.GroupId > 0 {
|
if task.GroupId > 0 {
|
||||||
group, err := models.TaskGroupGetById(task.GroupId)
|
group, err := models.GroupGetById(task.GroupId)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
groupName = group.GroupName
|
groupName = group.GroupName
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ func (self *TaskLogController) Detail() {
|
|||||||
//任务分组
|
//任务分组
|
||||||
groupName := "默认分组"
|
groupName := "默认分组"
|
||||||
if task.GroupId > 0 {
|
if task.GroupId > 0 {
|
||||||
group, err := models.TaskGroupGetById(task.GroupId)
|
group, err := models.GroupGetById(task.GroupId)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
groupName = group.GroupName
|
groupName = group.GroupName
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,8 +192,8 @@ func NewCommandJob(id int, serverId int, name string, command string) *Job {
|
|||||||
cmd.Start()
|
cmd.Start()
|
||||||
err, isTimeout := runCmdWithTimeout(cmd, timeout)
|
err, isTimeout := runCmdWithTimeout(cmd, timeout)
|
||||||
jobresult = new(JobResult)
|
jobresult = new(JobResult)
|
||||||
jobresult.OutMsg = libs.GbkAsUtf8(bufOut.String())
|
jobresult.OutMsg = bufOut.String()
|
||||||
jobresult.ErrMsg = libs.GbkAsUtf8(bufErr.String())
|
jobresult.ErrMsg = bufErr.String()
|
||||||
|
|
||||||
jobresult.IsOk = true
|
jobresult.IsOk = true
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -79,5 +79,5 @@ func GbkAsUtf8(str string) string {
|
|||||||
|
|
||||||
//任务识别码
|
//任务识别码
|
||||||
func JobKey(taskId, serverId int) int {
|
func JobKey(taskId, serverId int) int {
|
||||||
return taskId*10000000 + serverId
|
return taskId*100000 + serverId
|
||||||
}
|
}
|
||||||
|
|||||||
1
main.go
1
main.go
@@ -21,7 +21,6 @@ func init() {
|
|||||||
var StartTime = time.Now().Unix()
|
var StartTime = time.Now().Unix()
|
||||||
models.Init(StartTime)
|
models.Init(StartTime)
|
||||||
jobs.InitJobs()
|
jobs.InitJobs()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ package models
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/astaxie/beego/orm"
|
"github.com/astaxie/beego/orm"
|
||||||
@@ -116,3 +117,25 @@ func TaskDel(id int) (int64, error) {
|
|||||||
//_, err := orm.NewOrm().QueryTable(TableName("task")).Filter("id", id).Delete()
|
//_, err := orm.NewOrm().QueryTable(TableName("task")).Filter("id", id).Delete()
|
||||||
//return err
|
//return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//运行总次数
|
||||||
|
func TaskTotalRunNum() (int64, error) {
|
||||||
|
|
||||||
|
res := make(orm.Params)
|
||||||
|
_, err := orm.NewOrm().Raw("select sum(execute_times) as num,task_name from pp_task").RowsToMap(&res, "num", "task_name")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, _ := range res {
|
||||||
|
i64, err := strconv.ParseInt(k, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return i64, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -71,8 +71,22 @@ func TaskLogDelByTaskId(taskId int) (int64, error) {
|
|||||||
return orm.NewOrm().QueryTable(TableName("task_log")).Filter("task_id", taskId).Delete()
|
return orm.NewOrm().QueryTable(TableName("task_log")).Filter("task_id", taskId).Delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
// func GetTodaySuccessNum() (num, error) {
|
func GetLogNum(status int) (int64, error) {
|
||||||
// o := orm.NewOrm()
|
return orm.NewOrm().QueryTable(TableName("task_log")).Filter("status", status).Count()
|
||||||
// var r RawSeter
|
}
|
||||||
// r = o.Raw("SELECT COUNT(*) AS num WHERE create_time>=? AND status<0", "")
|
|
||||||
// }
|
type SumDays struct {
|
||||||
|
Day string
|
||||||
|
Sum int
|
||||||
|
}
|
||||||
|
|
||||||
|
func SumByDays(limit int, status string) orm.Params {
|
||||||
|
res := make(orm.Params)
|
||||||
|
_, err := orm.NewOrm().Raw("SELECT FROM_UNIXTIME(create_time,'%Y-%m-%d') days,COUNT(id) count FROM pp_task_log WHERE status in(?) GROUP BY days ORDER BY days DESC limit ?;",
|
||||||
|
status, limit).RowsToMap(&res, "days", "count")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|||||||
@@ -331,15 +331,15 @@ ALTER TABLE `pp_task_server` ADD `connection_type` TINYINT(1) NOT NULL DEFAULT '
|
|||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
BEGIN;
|
BEGIN;
|
||||||
ALTER TABLE `ppgo_job2`.`pp_task` CHANGE COLUMN `server_id` `server_ids` varchar(200) NOT NULL DEFAULT '0' COMMENT '服务器id字符串,英文都好隔开';
|
ALTER TABLE `pp_task` CHANGE COLUMN `server_id` `server_ids` varchar(200) NOT NULL DEFAULT '0' COMMENT '服务器id字符串,英文都好隔开';
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
BEGIN;
|
BEGIN;
|
||||||
ALTER TABLE `ppgo_job2`.`pp_task_log` ADD COLUMN `server_id` int(11) NOT NULL DEFAULT '-1' COMMENT '服务器ID,-1,异常' AFTER `task_id`, CHANGE COLUMN `output` `output` mediumtext NOT NULL COMMENT '任务输出' AFTER `server_id`, CHANGE COLUMN `error` `error` text NOT NULL COMMENT '错误信息' AFTER `output`, CHANGE COLUMN `status` `status` tinyint(4) NOT NULL COMMENT '状态' AFTER `error`, CHANGE COLUMN `process_time` `process_time` int(11) NOT NULL DEFAULT '0' COMMENT '消耗时间/毫秒' AFTER `status`, CHANGE COLUMN `create_time` `create_time` int(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT '创建时间' AFTER `process_time`;
|
ALTER TABLE `pp_task_log` ADD COLUMN `server_id` int(11) NOT NULL DEFAULT '-1' COMMENT '服务器ID,-1,异常' AFTER `task_id`, CHANGE COLUMN `output` `output` mediumtext NOT NULL COMMENT '任务输出' AFTER `server_id`, CHANGE COLUMN `error` `error` text NOT NULL COMMENT '错误信息' AFTER `output`, CHANGE COLUMN `status` `status` tinyint(4) NOT NULL COMMENT '状态' AFTER `error`, CHANGE COLUMN `process_time` `process_time` int(11) NOT NULL DEFAULT '0' COMMENT '消耗时间/毫秒' AFTER `status`, CHANGE COLUMN `create_time` `create_time` int(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT '创建时间' AFTER `process_time`;
|
||||||
ALTER TABLE `ppgo_job2`.`pp_task_log` ADD COLUMN `server_name` varchar(60) NOT NULL DEFAULT '\"\"' COMMENT '服务器名称' AFTER `server_id`, CHANGE COLUMN `output` `output` mediumtext NOT NULL COMMENT '任务输出' AFTER `server_name`, CHANGE COLUMN `error` `error` text NOT NULL COMMENT '错误信息' AFTER `output`, CHANGE COLUMN `status` `status` tinyint(4) NOT NULL COMMENT '状态' AFTER `error`, CHANGE COLUMN `process_time` `process_time` int(11) NOT NULL DEFAULT '0' COMMENT '消耗时间/毫秒' AFTER `status`, CHANGE COLUMN `create_time` `create_time` int(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT '创建时间' AFTER `process_time`;
|
ALTER TABLE `pp_task_log` ADD COLUMN `server_name` varchar(60) NOT NULL DEFAULT '\"\"' COMMENT '服务器名称' AFTER `server_id`, CHANGE COLUMN `output` `output` mediumtext NOT NULL COMMENT '任务输出' AFTER `server_name`, CHANGE COLUMN `error` `error` text NOT NULL COMMENT '错误信息' AFTER `output`, CHANGE COLUMN `status` `status` tinyint(4) NOT NULL COMMENT '状态' AFTER `error`, CHANGE COLUMN `process_time` `process_time` int(11) NOT NULL DEFAULT '0' COMMENT '消耗时间/毫秒' AFTER `status`, CHANGE COLUMN `create_time` `create_time` int(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT '创建时间' AFTER `process_time`;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
BEGIN;
|
BEGIN;
|
||||||
ALTER TABLE `ppgo_job2`.`pp_task` CHANGE COLUMN `is_notify` ` is_notify` tinyint(1) UNSIGNED NOT NULL DEFAULT '0' COMMENT '0-不通知,1-通知', ADD COLUMN `server_type` tinyint(1) UNSIGNED NOT NULL DEFAULT '1' COMMENT '执行策略:0-同时执行,1-轮询执行' AFTER `update_id`;
|
ALTER TABLE `pp_task` CHANGE COLUMN `is_notify` `is_notify` tinyint(1) UNSIGNED NOT NULL DEFAULT '0' COMMENT '0-不通知,1-通知', ADD COLUMN `server_type` tinyint(1) UNSIGNED NOT NULL DEFAULT '1' COMMENT '执行策略:0-同时执行,1-轮询执行' AFTER `update_id`;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
SET FOREIGN_KEY_CHECKS = 1;
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
|
|||||||
13
static/echarts/echarts.min.js
vendored
Normal file
13
static/echarts/echarts.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1,9 +1,10 @@
|
|||||||
<div class="layui-row ml20" >
|
<div class="layui-row ml20" >
|
||||||
<style>
|
<style>
|
||||||
.info-box {
|
.info-box {
|
||||||
height: 85px;
|
height: 60px;
|
||||||
background-color: white;
|
background-color: #f2f2f2;
|
||||||
background-color: #ecf0f5;
|
border: 1px solid #f2f2f2;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -14,34 +15,40 @@
|
|||||||
border-bottom-left-radius: 2px;
|
border-bottom-left-radius: 2px;
|
||||||
display: block;
|
display: block;
|
||||||
float: left;
|
float: left;
|
||||||
height: 85px;
|
height: 60px;
|
||||||
width: 85px;
|
width: 60px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 45px;
|
font-size: 40px;
|
||||||
line-height: 85px;
|
line-height: 60px;
|
||||||
background: rgba(0, 0, 0, 0.2);
|
/*background: rgba(0, 0, 0, 0.2);*/
|
||||||
|
background-color:#efefef !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-box .info-box-content {
|
.info-box .info-box-content {
|
||||||
padding: 5px 10px;
|
padding: 1px 5px;
|
||||||
margin-left: 85px;
|
margin-left: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-box-content .info-box-text{
|
.info-box-content .info-box-text{
|
||||||
font-size: 18px;
|
font-size: 16px;
|
||||||
width: 100%;
|
width: 80%;
|
||||||
display: block;
|
display: block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #999;
|
color: #888;
|
||||||
margin: 10px auto;
|
margin: 3px auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-box-content .info-box-number{
|
.info-box-content .info-box-number{
|
||||||
font-size: 24px;
|
font-size: 20px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: block;
|
display: block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inner-icon{
|
||||||
|
font-size:24px;
|
||||||
|
color: #efefef !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="layui-row">
|
<div class="layui-row">
|
||||||
@@ -51,153 +58,347 @@
|
|||||||
<div class="layui-row layui-col-space15">
|
<div class="layui-row layui-col-space15">
|
||||||
<div class="layui-col-md3">
|
<div class="layui-col-md3">
|
||||||
<div class="info-box">
|
<div class="info-box">
|
||||||
<span class="info-box-icon" style="background-color:#00a65a !important;color:white;"><i class="fa fa-check" aria-hidden="true"></i></span>
|
{{/*<span class="info-box-icon" style="background-color:#f39c12 !important;color:white;"><i class="fa fa-hourglass" aria-hidden="true"></i></span>*/}}
|
||||||
|
<span class="fa-stack fa-lg info-box-icon" >
|
||||||
|
<i class="fa fa-circle fa-stack-1x" style="color:#fff !important;">
|
||||||
|
<i class="fa fa-hourglass fa-inverse fa-stack-1x inner-icon" ></i>
|
||||||
|
</i>
|
||||||
|
</span>
|
||||||
<div class="info-box-content">
|
<div class="info-box-content">
|
||||||
<span class="info-box-text">最近执行成功</span>
|
<span class="info-box-text">即将执行的任务</span>
|
||||||
<span class="info-box-number">{{.okJob}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-col-md3">
|
|
||||||
<div class="info-box">
|
|
||||||
<span class="info-box-icon" style="background-color:#dd4b39 !important;color:white;"><i class="fa fa-exclamation" aria-hidden="true"></i></span>
|
|
||||||
<div class="info-box-content">
|
|
||||||
<span class="info-box-text">最近执行失败</span>
|
|
||||||
<span class="info-box-number">{{.failJob}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-col-md3">
|
|
||||||
<div class="info-box">
|
|
||||||
<span class="info-box-icon" style="background-color:#f39c12 !important;color:white;"><i class="fa fa-hourglass" aria-hidden="true"></i></span>
|
|
||||||
<div class="info-box-content">
|
|
||||||
<span class="info-box-text">即将执行的任务</span>
|
|
||||||
<span class="info-box-number">{{.startJob}}</span>
|
<span class="info-box-number">{{.startJob}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="layui-col-md3">
|
<div class="layui-col-md3">
|
||||||
<div class="info-box">
|
<div class="info-box">
|
||||||
<span class="info-box-icon" style="background-color:#00c0ef !important;color:white;"><i class="fa fa-database" aria-hidden="true"></i></span>
|
<span class="fa-stack fa-lg info-box-icon" >
|
||||||
|
<i class="fa fa-circle fa-stack-1x" style="color:#fff !important;">
|
||||||
|
<i class="fa fa-question fa-inverse fa-stack-1x inner-icon" ></i>
|
||||||
|
</i>
|
||||||
|
</span>
|
||||||
|
<div class="info-box-content">
|
||||||
|
<span class="info-box-text">待审核任务数量</span>
|
||||||
|
<span class="info-box-number">{{.totalAuditTask}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-col-md3">
|
||||||
|
<div class="info-box">
|
||||||
|
<span class="fa-stack fa-lg info-box-icon" >
|
||||||
|
<i class="fa fa-circle fa-stack-1x" style="color:#fff !important;">
|
||||||
|
<i class="fa fa-check fa-inverse fa-stack-1x inner-icon" ></i>
|
||||||
|
</i>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="info-box-content">
|
||||||
|
<span class="info-box-text">近期执行成功</span>
|
||||||
|
<span class="info-box-number">{{.successNum}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-col-md3">
|
||||||
|
<div class="info-box">
|
||||||
|
<span class="fa-stack fa-lg info-box-icon" >
|
||||||
|
<i class="fa fa-circle fa-stack-1x" style="color:#fff !important;">
|
||||||
|
<i class="fa fa-exclamation fa-inverse fa-stack-1x inner-icon" ></i>
|
||||||
|
</i>
|
||||||
|
</span>
|
||||||
|
<div class="info-box-content">
|
||||||
|
<span class="info-box-text">近期执行失败</span>
|
||||||
|
<span class="info-box-number">{{.errorNum}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-col-md3">
|
||||||
|
<div class="info-box">
|
||||||
|
<span class="fa-stack fa-lg info-box-icon" >
|
||||||
|
<i class="fa fa-circle fa-stack-1x" style="color:#fff !important;">
|
||||||
|
<i class="fa fa-user fa-inverse fa-stack-1x inner-icon" ></i>
|
||||||
|
</i>
|
||||||
|
</span>
|
||||||
|
<div class="info-box-content">
|
||||||
|
<span class="info-box-text">当前用户总数</span>
|
||||||
|
<span class="info-box-number">{{.userNum}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-col-md3">
|
||||||
|
<div class="info-box">
|
||||||
|
<span class="fa-stack fa-lg info-box-icon" >
|
||||||
|
<i class="fa fa-circle fa-stack-1x" style="color:#fff !important;">
|
||||||
|
<i class="fa fa-tasks fa-inverse fa-stack-1x inner-icon" ></i>
|
||||||
|
</i>
|
||||||
|
</span>
|
||||||
|
|
||||||
<div class="info-box-content">
|
<div class="info-box-content">
|
||||||
<span class="info-box-text">定时任务总数量</span>
|
<span class="info-box-text">定时任务总数量</span>
|
||||||
<span class="info-box-number">{{.totalJob}}</span>
|
<span class="info-box-number">{{.totalJob}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="layui-col-md3">
|
||||||
|
<div class="info-box">
|
||||||
|
<span class="fa-stack fa-lg info-box-icon" >
|
||||||
|
<i class="fa fa-circle fa-stack-1x" style="color:#fff !important;">
|
||||||
|
<i class="fa fa-calculator fa-inverse fa-stack-1x inner-icon" ></i>
|
||||||
|
</i>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="info-box-content">
|
||||||
|
<span class="info-box-text">累计运行次数</span>
|
||||||
|
<span class="info-box-number">{{.TaskTotalRunNum}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-col-md3">
|
||||||
|
<div class="info-box">
|
||||||
|
<span class="fa-stack fa-lg info-box-icon" >
|
||||||
|
<i class="fa fa-circle fa-stack-1x" style="color:#fff !important;">
|
||||||
|
<i class="fa fa-sticky-note fa-inverse fa-stack-1x inner-icon" ></i>
|
||||||
|
</i>
|
||||||
|
</span>
|
||||||
|
<div class="info-box-content">
|
||||||
|
<span class="info-box-text">当前日志总量</span>
|
||||||
|
<span class="info-box-number">{{.totalLog}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-col-md4">
|
|
||||||
<div class="layui-card">
|
|
||||||
<div class="layui-card-header">最近执行的任务</div>
|
|
||||||
<div class="layui-card-body" style="height: 465px; padding-bottom: 10px; overflow: auto">
|
|
||||||
<table class="layui-table" lay-size="sm">
|
|
||||||
<colgroup>
|
|
||||||
<col width="50">
|
|
||||||
<col >
|
|
||||||
<col >
|
|
||||||
<col>
|
|
||||||
</colgroup>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>序号</th>
|
|
||||||
<th>任务名称</th>
|
|
||||||
<th>开始时间</th>
|
|
||||||
<th>执行结果</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{{range $k, $v := .recentLogs}}
|
|
||||||
<tr>
|
|
||||||
<td>{{$k}}</td>
|
|
||||||
<td><a href="{{urlfor "TaskLogController.Detail" "id" $v.id}}" class="news-item-title">
|
|
||||||
{{$v.task_name}} # {{$v.id}}
|
|
||||||
</a></td>
|
|
||||||
<td>{{$v.start_time}}</td>
|
|
||||||
<td>{{if eq $v.status 0}}
|
|
||||||
正常
|
|
||||||
{{else if eq $v.status -1}}
|
|
||||||
<span style="color:red">异常</span>
|
|
||||||
{{else}}
|
|
||||||
<span style="color:red">超时</span>
|
|
||||||
{{end}}</td>
|
|
||||||
</tr>
|
|
||||||
{{else}}
|
|
||||||
<tr>
|
|
||||||
<td colspan="3">暂无信息</td>
|
|
||||||
</tr>
|
|
||||||
{{end}}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-col-md4">
|
|
||||||
<div class="layui-card" style="background: #fff">
|
|
||||||
<div class="layui-card-header">即将执行的任务</div>
|
|
||||||
<div class="layui-card-body" style="height: 465px; padding-bottom: 10px; overflow: auto">
|
|
||||||
<table class="layui-table" lay-size="sm">
|
|
||||||
<colgroup>
|
|
||||||
<col>
|
|
||||||
<col>
|
|
||||||
</colgroup>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>任务名称</th>
|
|
||||||
<th>执行时间</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
|
|
||||||
{{range $k, $v := .jobs}}
|
</div>
|
||||||
<tr>
|
</div>
|
||||||
<td><a href="{{urlfor "TaskController.Logs" "id" $v.task_id}}" class="news-item-title">{{$v.task_name}}-{{$v.task_group}} # {{$v.task_id}}</a></td>
|
<div class="layui-row">
|
||||||
<td>{{$v.next_time}}</td>
|
<div class="layui-col-md12">
|
||||||
</tr>
|
<div class="layui-card-body">
|
||||||
{{else}}
|
<div class="layui-tab">
|
||||||
<tr>
|
<ul class="layui-tab-title">
|
||||||
<td colspan="2">暂无信息</td>
|
<li class="layui-this">系统概况</li>
|
||||||
</tr>
|
<li>即将开始的任务</li>
|
||||||
{{end}}
|
<li>最近失败的任务</li>
|
||||||
</tbody>
|
</ul>
|
||||||
</table>
|
<div class="layui-tab-content">
|
||||||
</div>
|
<div class="layui-tab-item layui-show">
|
||||||
</div>
|
<div class="layui-col-md8" id="charts-box">
|
||||||
</div>
|
{{/*图表*/}}
|
||||||
<div class="layui-col-md4">
|
<div id="main" style=" height: 528px;"></div>
|
||||||
<div class="layui-card" style="background: #fff">
|
</div>
|
||||||
<div class="layui-card-header">系统概况</div>
|
|
||||||
<div class="layui-card-body" style="height: 465px; padding-bottom: 10px; overflow: auto">
|
|
||||||
<table class="layui-table" lay-size="sm">
|
|
||||||
<colgroup>
|
|
||||||
<col>
|
|
||||||
<col>
|
|
||||||
</colgroup>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>参数</th>
|
|
||||||
<th>值</th>
|
|
||||||
|
|
||||||
</tr>
|
<div class="layui-col-md4" >
|
||||||
</thead>
|
{{/*系统概况*/}}
|
||||||
<tbody>
|
<div class="layui-card" style="background: #fff" id="sys">
|
||||||
{{range $k, $v := .sysInfo}}
|
<div class="layui-card-header">系统概况</div>
|
||||||
<tr>
|
<div class="layui-card-body" style="height: 465px; padding-bottom: 10px; overflow: auto">
|
||||||
<td># {{$k}} </td>
|
<table class="layui-table" lay-size="sm">
|
||||||
<td>{{$v}}</td>
|
<colgroup>
|
||||||
</tr>
|
<col>
|
||||||
{{else}}
|
<col>
|
||||||
<tr>
|
</colgroup>
|
||||||
<td colspan="2">暂无信息</td>
|
<thead>
|
||||||
</tr>
|
<tr>
|
||||||
{{end}}
|
<th>参数</th>
|
||||||
</tbody>
|
<th>值</th>
|
||||||
</table>
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{range $k, $v := .sysInfo}}
|
||||||
|
<tr>
|
||||||
|
<td># {{$k}} </td>
|
||||||
|
<td>{{$v}}</td>
|
||||||
|
</tr>
|
||||||
|
{{else}}
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">暂无信息</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-tab-item">
|
||||||
|
<div class="layui-card" style="background: #fff">
|
||||||
|
<div class="layui-card-header">即将执行的任务</div>
|
||||||
|
<div class="layui-card-body" style="height: 465px; padding-bottom: 10px; overflow: auto">
|
||||||
|
<table class="layui-table" lay-size="sm">
|
||||||
|
<colgroup>
|
||||||
|
<col>
|
||||||
|
<col>
|
||||||
|
</colgroup>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>任务名称</th>
|
||||||
|
<th>执行时间</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{range $k, $v := .jobs}}
|
||||||
|
<tr>
|
||||||
|
<td><a href="{{urlfor "TaskController.Logs" "id" $v.task_id}}" class="news-item-title">{{$v.task_name}}-{{$v.task_group}} # {{$v.task_id}}</a></td>
|
||||||
|
<td>{{$v.next_time}}</td>
|
||||||
|
</tr>
|
||||||
|
{{else}}
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">暂无信息</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-tab-item">
|
||||||
|
{{/*执行失败的任务*/}}
|
||||||
|
<div class="layui-card">
|
||||||
|
<div class="layui-card-header">最近执行的任务</div>
|
||||||
|
<div class="layui-card-body" style="height: 465px; padding-bottom: 10px; overflow: auto">
|
||||||
|
<table class="layui-table" lay-size="sm">
|
||||||
|
<colgroup>
|
||||||
|
<col width="50">
|
||||||
|
<col >
|
||||||
|
<col >
|
||||||
|
<col>
|
||||||
|
</colgroup>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>序号</th>
|
||||||
|
<th>任务名称</th>
|
||||||
|
<th>开始时间</th>
|
||||||
|
<th>执行结果</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{range $k, $v := .errLogs}}
|
||||||
|
<tr>
|
||||||
|
<td>{{$k}}</td>
|
||||||
|
<td><a href="javascript:;" onclick="logDetail({{$v.id}});" class="news-item-title">
|
||||||
|
{{$v.task_name}} # {{$v.id}}
|
||||||
|
</a></td>
|
||||||
|
<td>{{$v.start_time}}</td>
|
||||||
|
<td>{{if eq $v.status 0}}
|
||||||
|
正常
|
||||||
|
{{else if eq $v.status -1}}
|
||||||
|
<span style="color:red">异常</span>
|
||||||
|
{{else}}
|
||||||
|
<span style="color:red">超时</span>
|
||||||
|
{{end}}</td>
|
||||||
|
</tr>
|
||||||
|
{{else}}
|
||||||
|
<tr>
|
||||||
|
<td colspan="3">暂无信息</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="/static/echarts/echarts.min.js"></script>
|
||||||
|
<script src="/static/layui/layui.js"></script>
|
||||||
|
<script>
|
||||||
|
var $;
|
||||||
|
//注意:选项卡 依赖 element 模块,否则无法进行功能性操作
|
||||||
|
layui.use('element', function(){
|
||||||
|
var element = layui.element;
|
||||||
|
|
||||||
|
$ = layui.$;
|
||||||
|
resizeChartbox();
|
||||||
|
window.onresize = function(){
|
||||||
|
resizeChartbox();
|
||||||
|
}
|
||||||
|
function resizeChartbox()
|
||||||
|
{
|
||||||
|
height = $("#sys").height();
|
||||||
|
width = $("#charts-box").width();
|
||||||
|
$("#main").width(width-200);
|
||||||
|
$("#main").height(height);
|
||||||
|
}
|
||||||
|
element.render();
|
||||||
|
//…
|
||||||
|
});
|
||||||
|
|
||||||
|
function logDetail(id){
|
||||||
|
window.parent.openTab("/tasklog/detail?id="+id,id+' 日志详情',"admin_log_detail-"+id,'');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 基于准备好的dom,初始化echarts实例
|
||||||
|
var myChart = echarts.init(document.getElementById('main'));
|
||||||
|
|
||||||
|
|
||||||
|
// 指定图表的配置项和数据
|
||||||
|
var option = {
|
||||||
|
title: {
|
||||||
|
text: '运行概况'
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data:['任务执行失败','任务执行超时','任务执行成功']
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '3%',
|
||||||
|
right: '4%',
|
||||||
|
bottom: '3%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
toolbox: {
|
||||||
|
feature: {
|
||||||
|
saveAsImage: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: false,
|
||||||
|
data: {{.days}}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value'
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name:'任务执行失败',
|
||||||
|
type:'line',
|
||||||
|
stack: '总量',
|
||||||
|
data:{{.errNum}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'任务执行超时',
|
||||||
|
type:'line',
|
||||||
|
stack: '总量',
|
||||||
|
data:{{.expiredNum}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'任务执行成功',
|
||||||
|
type:'line',
|
||||||
|
stack: '总量',
|
||||||
|
data:{{.okNum}}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 使用刚指定的配置项和数据显示图表。
|
||||||
|
myChart.setOption(option);
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
,url: '/task/table?status=2'
|
,url: '/task/table?status=2'
|
||||||
,cols: [[
|
,cols: [[
|
||||||
{checkbox: true, fixed: true},
|
{checkbox: true, fixed: true},
|
||||||
{field:'id', title: 'ID', align:'center',sort: true, width:100}
|
{field:'id', title: 'ID', align:'center',sort: true, width:80}
|
||||||
,{field:'task_name',title: '任务名称'}
|
,{field:'task_name',title: '任务名称'}
|
||||||
,{field:'cron_spec',title: '执行时间', width:150}
|
,{field:'cron_spec',title: '执行时间', width:150}
|
||||||
,{field:'pre_time', width:170,title: '上次执行时间'}
|
,{field:'pre_time', width:170,title: '上次执行时间'}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
{{/*<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="status">启|停</a>*/}}
|
{{/*<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="status">启|停</a>*/}}
|
||||||
{{/*<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>*/}}
|
{{/*<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>*/}}
|
||||||
<a class="layui-btn layui-btn-xs " lay-event="detail">详细</a>
|
<a class="layui-btn layui-btn-xs " lay-event="detail">详细</a>
|
||||||
{{/*<a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="run">测试</a>*/}}
|
<a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="run">测试</a>
|
||||||
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="log">日志</a>
|
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="log">日志</a>
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
@@ -58,13 +58,13 @@
|
|||||||
,url: '/task/table'
|
,url: '/task/table'
|
||||||
,cols: [[
|
,cols: [[
|
||||||
{checkbox: true, fixed: true},
|
{checkbox: true, fixed: true},
|
||||||
{field:'id', title: 'ID', align:'center', width:100,sort: true}
|
{field:'id', title: 'ID', align:'center', width:80,sort: true}
|
||||||
,{field:'task_name', title: '任务名称'}
|
,{field:'task_name', title: '任务名称'}
|
||||||
,{field:'cron_spec',title: '时间表达式', width:150}
|
,{field:'cron_spec',title: '时间表达式', width:100}
|
||||||
,{field:'next_time', width:170,title: '下次执行时间'}
|
,{field:'next_time', width:170,title: '下次执行时间'}
|
||||||
,{field:'pre_time', title: '上次执行时间',width:170,}
|
,{field:'pre_time', title: '上次执行时间',width:170,}
|
||||||
,{field:'execute_times', title: '次数',width:100}
|
,{field:'execute_times', title: '次数',width:100}
|
||||||
,{width:120, align:'center', title:'操作', toolbar: '#bar'}
|
,{width:180, align:'center', title:'操作', toolbar: '#bar'}
|
||||||
]]
|
]]
|
||||||
,id: 'listReload'
|
,id: 'listReload'
|
||||||
,page: true
|
,page: true
|
||||||
|
|||||||
Reference in New Issue
Block a user