提交
This commit is contained in:
9
modules/task/README.md
Normal file
9
modules/task/README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# task
|
||||
|
||||
任务管理模块,提供基于`coolfun`c 的任务管理功能
|
||||
|
||||
## 资源打包命令
|
||||
|
||||
```bash
|
||||
gf pack modules/task/resource modules/task/packed/packed.go -p modules/task/resource
|
||||
```
|
||||
1
modules/task/controller/admin/admin.go
Normal file
1
modules/task/controller/admin/admin.go
Normal file
@@ -0,0 +1 @@
|
||||
package admin
|
||||
94
modules/task/controller/admin/task_info.go
Normal file
94
modules/task/controller/admin/task_info.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/cool-team-official/cool-admin-go/cool"
|
||||
"github.com/cool-team-official/cool-admin-go/modules/task/service"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
type TaskInfoController struct {
|
||||
*cool.Controller
|
||||
}
|
||||
|
||||
func init() {
|
||||
var task_info_controller = &TaskInfoController{
|
||||
&cool.Controller{
|
||||
Prefix: "/admin/task/info",
|
||||
Api: []string{"Add", "Delete", "Update", "Info", "List", "Page", "Start", "Stop"},
|
||||
Service: service.NewTaskInfoService(),
|
||||
},
|
||||
}
|
||||
// 注册路由
|
||||
cool.RegisterController(task_info_controller)
|
||||
}
|
||||
|
||||
// TaskInfoStopReq 请求参数
|
||||
type TaskInfoStopReq struct {
|
||||
g.Meta `path:"/stop" method:"GET"`
|
||||
ID int64 `json:"id" v:"required#请输入id"`
|
||||
}
|
||||
|
||||
// Stop 停止任务
|
||||
func (c *TaskInfoController) Stop(ctx g.Ctx, req *TaskInfoStopReq) (res *cool.BaseRes, err error) {
|
||||
|
||||
err = cool.ClusterRunFunc(ctx, "TaskStopFunc("+gconv.String(req.ID)+")")
|
||||
if err != nil {
|
||||
return cool.Fail(err.Error()), err
|
||||
}
|
||||
res = cool.Ok("停止成功")
|
||||
return
|
||||
}
|
||||
|
||||
// TaskInfoStartReq 请求参数
|
||||
type TaskInfoStartReq struct {
|
||||
g.Meta `path:"/start" method:"GET"`
|
||||
ID int64 `json:"id" v:"required#请输入id"`
|
||||
}
|
||||
|
||||
// Start 启动任务
|
||||
func (c *TaskInfoController) Start(ctx g.Ctx, req *TaskInfoStartReq) (res *cool.BaseRes, err error) {
|
||||
|
||||
err = cool.ClusterRunFunc(ctx, "TaskStartFunc("+gconv.String(req.ID)+")")
|
||||
if err != nil {
|
||||
return cool.Fail(err.Error()), err
|
||||
}
|
||||
res = cool.Ok("启动成功")
|
||||
return
|
||||
}
|
||||
|
||||
// TaskInfoOnceReq 请求参数
|
||||
type TaskInfoOnceReq struct {
|
||||
g.Meta `path:"/once" method:"POST"`
|
||||
ID int64 `json:"id" v:"required#请输入id"`
|
||||
}
|
||||
|
||||
// Once 执行一次
|
||||
func (c *TaskInfoController) Once(ctx g.Ctx, req *TaskInfoOnceReq) (res *cool.BaseRes, err error) {
|
||||
err = c.Service.(*service.TaskInfoService).Once(ctx, req.ID)
|
||||
if err != nil {
|
||||
return cool.Fail(err.Error()), err
|
||||
}
|
||||
res = cool.Ok("执行成功")
|
||||
return
|
||||
}
|
||||
|
||||
// TaskInfoLogReq 请求参数
|
||||
type TaskInfoLogReq struct {
|
||||
g.Meta `path:"/log" method:"GET"`
|
||||
ID int64 `json:"id"`
|
||||
Status int `json:"status"`
|
||||
}
|
||||
|
||||
// Log 任务日志
|
||||
func (c *TaskInfoController) Log(ctx g.Ctx, req *TaskInfoLogReq) (res *cool.BaseRes, err error) {
|
||||
r := ghttp.RequestFromCtx(ctx)
|
||||
param := r.GetQueryMapStrStr()
|
||||
data, err := c.Service.(*service.TaskInfoService).Log(ctx, param)
|
||||
if err != nil {
|
||||
return cool.Fail(err.Error()), err
|
||||
}
|
||||
res = cool.Ok(data)
|
||||
return
|
||||
}
|
||||
1
modules/task/controller/app/app.go
Normal file
1
modules/task/controller/app/app.go
Normal file
@@ -0,0 +1 @@
|
||||
package app
|
||||
7
modules/task/controller/controller.go
Normal file
7
modules/task/controller/controller.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
_ "github.com/cool-team-official/cool-admin-go/modules/task/controller/admin"
|
||||
_ "github.com/cool-team-official/cool-admin-go/modules/task/controller/app"
|
||||
_ "github.com/cool-team-official/cool-admin-go/modules/task/service"
|
||||
)
|
||||
46
modules/task/funcs/task_add_task.go
Normal file
46
modules/task/funcs/task_add_task.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package funcs
|
||||
|
||||
import (
|
||||
"github.com/cool-team-official/cool-admin-go/cool"
|
||||
"github.com/cool-team-official/cool-admin-go/modules/task/model"
|
||||
"github.com/cool-team-official/cool-admin-go/modules/task/service"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
type TaskAddTask struct {
|
||||
}
|
||||
|
||||
func (t *TaskAddTask) Func(ctx g.Ctx, id string) error {
|
||||
taskInfo := model.NewTaskInfo()
|
||||
result, err := cool.DBM(taskInfo).Where("id = ?", id).One()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if result["taskType"].Int() == 1 {
|
||||
every := result["every"].Uint() / 1000
|
||||
cron := "@every " + gconv.String(every) + "s"
|
||||
funcstring := result["service"].String()
|
||||
startDate := result["startDate"].String()
|
||||
err = service.EnableTask(ctx, id, funcstring, cron, startDate)
|
||||
} else {
|
||||
cron := result["cron"].String()
|
||||
funcstring := result["service"].String()
|
||||
startDate := result["startDate"].String()
|
||||
err = service.EnableTask(ctx, id, funcstring, cron, startDate)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *TaskAddTask) IsSingleton() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *TaskAddTask) IsAllWorker() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func init() {
|
||||
cool.RegisterFunc("TaskAddTask", &TaskAddTask{})
|
||||
}
|
||||
33
modules/task/funcs/task_stop_func.go
Normal file
33
modules/task/funcs/task_stop_func.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package funcs
|
||||
|
||||
import (
|
||||
"github.com/cool-team-official/cool-admin-go/cool"
|
||||
"github.com/cool-team-official/cool-admin-go/modules/task/model"
|
||||
"github.com/cool-team-official/cool-admin-go/modules/task/service"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type TaskStopFunc struct {
|
||||
}
|
||||
|
||||
func (t *TaskStopFunc) Func(ctx g.Ctx, id string) error {
|
||||
taskInfo := model.NewTaskInfo()
|
||||
_, err := cool.DBM(taskInfo).Where("id = ?", id).Update(g.Map{"status": 0})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return service.DisableTask(ctx, id)
|
||||
}
|
||||
|
||||
func (t *TaskStopFunc) IsSingleton() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *TaskStopFunc) IsAllWorker() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func init() {
|
||||
cool.RegisterFunc("TaskStopFunc", &TaskStopFunc{})
|
||||
}
|
||||
24
modules/task/funcs/task_testfunc.go
Normal file
24
modules/task/funcs/task_testfunc.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package funcs
|
||||
|
||||
import (
|
||||
"github.com/cool-team-official/cool-admin-go/cool"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type TaskTest struct {
|
||||
}
|
||||
|
||||
func (t *TaskTest) Func(ctx g.Ctx, param string) error {
|
||||
g.Log().Info(ctx, "TaskTest Run ~~~~~~~~~~~~~~~~", param)
|
||||
return nil
|
||||
}
|
||||
func (t *TaskTest) IsSingleton() bool {
|
||||
return false
|
||||
}
|
||||
func (t *TaskTest) IsAllWorker() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func init() {
|
||||
cool.RegisterFunc("TaskTest", &TaskTest{})
|
||||
}
|
||||
49
modules/task/funcs/tast_start_func.go
Normal file
49
modules/task/funcs/tast_start_func.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package funcs
|
||||
|
||||
import (
|
||||
"github.com/cool-team-official/cool-admin-go/cool"
|
||||
"github.com/cool-team-official/cool-admin-go/modules/task/model"
|
||||
"github.com/cool-team-official/cool-admin-go/modules/task/service"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
type TaskStartFunc struct {
|
||||
}
|
||||
|
||||
func (t *TaskStartFunc) Func(ctx g.Ctx, id string) error {
|
||||
taskInfo := model.NewTaskInfo()
|
||||
_, err := cool.DBM(taskInfo).Where("id = ?", id).Update(g.Map{"status": 1})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := cool.DBM(taskInfo).Where("id = ?", id).One()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if result["taskType"].Int() == 1 {
|
||||
every := result["every"].Uint() / 1000
|
||||
cron := "@every " + gconv.String(every) + "s"
|
||||
funcstring := result["service"].String()
|
||||
startDate := result["startDate"].String()
|
||||
err = service.EnableTask(ctx, id, funcstring, cron, startDate)
|
||||
|
||||
} else {
|
||||
cron := result["cron"].String()
|
||||
funcstring := result["service"].String()
|
||||
startDate := result["startDate"].String()
|
||||
err = service.EnableTask(ctx, id, funcstring, cron, startDate)
|
||||
}
|
||||
return err
|
||||
|
||||
}
|
||||
func (t *TaskStartFunc) IsSingleton() bool {
|
||||
return false
|
||||
}
|
||||
func (t *TaskStartFunc) IsAllWorker() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func init() {
|
||||
cool.RegisterFunc("TaskStartFunc", &TaskStartFunc{})
|
||||
}
|
||||
40
modules/task/go.mod
Normal file
40
modules/task/go.mod
Normal file
@@ -0,0 +1,40 @@
|
||||
module github.com/cool-team-official/cool-admin-go/modules/task
|
||||
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/cool-team-official/cool-admin-go/cool v1.5.9
|
||||
github.com/gogf/gf/v2 v2.6.3
|
||||
github.com/robfig/cron v1.2.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.1 // indirect
|
||||
github.com/grokify/html-strip-tags-go v0.1.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rogpeppe/go-internal v1.6.1 // indirect
|
||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
golang.org/x/net v0.21.0 // indirect
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gorm.io/gorm v1.25.7 // indirect
|
||||
)
|
||||
81
modules/task/go.sum
Normal file
81
modules/task/go.sum
Normal file
@@ -0,0 +1,81 @@
|
||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
|
||||
github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
|
||||
github.com/cool-team-official/cool-admin-go/cool v1.5.9 h1:mvZkckumdnhkr8BGRbB+FKmUeP3tbxmyvSxfNyZAlhE=
|
||||
github.com/cool-team-official/cool-admin-go/cool v1.5.9/go.mod h1:kle9oSJM+yl8ZtQwZFL8PWbz7ByI8Glj1431njGbWPo=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/gogf/gf/v2 v2.6.3 h1:DoqeuwU98wotpFoDSQEx8RZbmJdK8KdGiJtzJeqpyIo=
|
||||
github.com/gogf/gf/v2 v2.6.3/go.mod h1:x2XONYcI4hRQ/4gMNbWHmZrNzSEIg20s2NULbzom5k0=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||
github.com/grokify/html-strip-tags-go v0.1.0 h1:03UrQLjAny8xci+R+qjCce/MYnpNXCtgzltlQbOBae4=
|
||||
github.com/grokify/html-strip-tags-go v0.1.0/go.mod h1:ZdzgfHEzAfz9X6Xe5eBLVblWIxXfYSQ40S/VKrAOGpc=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
|
||||
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
||||
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
||||
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
|
||||
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/gorm v1.25.7 h1:VsD6acwRjz2zFxGO50gPO6AkNs7KKnvfzUjHQhZDz/A=
|
||||
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
1
modules/task/middleware/middleware.go
Normal file
1
modules/task/middleware/middleware.go
Normal file
@@ -0,0 +1 @@
|
||||
package middleware
|
||||
1
modules/task/model/model.go
Normal file
1
modules/task/model/model.go
Normal file
@@ -0,0 +1 @@
|
||||
package model
|
||||
50
modules/task/model/task_info.go
Normal file
50
modules/task/model/task_info.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/cool-team-official/cool-admin-go/cool"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
const TableNameTaskInfo = "task_info"
|
||||
|
||||
// TaskInfo mapped from table <task_info>
|
||||
type TaskInfo struct {
|
||||
*cool.Model
|
||||
JobId string `json:"jobId" gorm:"column:jobId;type:varchar(255);comment:任务ID"`
|
||||
RepeatConf string `json:"repeatConf" gorm:"column:repeatConf;comment:重复配置"`
|
||||
Name string `json:"name" gorm:"column:name;type:varchar(255);comment:任务名称"`
|
||||
Cron string `json:"cron" gorm:"column:cron;type:varchar(255);comment:cron表达式"`
|
||||
Limit int `json:"limit" gorm:"column:limit;comment:限制次数 不传为不限制"`
|
||||
Every int `json:"every" gorm:"column:every;comment:间隔时间 单位秒"`
|
||||
Remark string `json:"remark" gorm:"column:remark;type:varchar(255);comment:备注"`
|
||||
Status int `json:"status" gorm:"column:status;comment:状态 0:关闭 1:开启"`
|
||||
StartDate gtime.Time `json:"startDate" gorm:"column:startDate;comment:开始时间"`
|
||||
EndDate gtime.Time `json:"endDate" gorm:"column:endDate;comment:结束时间"`
|
||||
Data string `json:"data" gorm:"column:data;type:varchar(255);comment:数据"`
|
||||
Service string `json:"service" gorm:"column:service;type:varchar(255);comment:执行的服务"`
|
||||
Type int `json:"type" gorm:"column:type;comment:类型 0:系统 1:用户"`
|
||||
NextRunTime gtime.Time `json:"nextRunTime" gorm:"column:nextRunTime;comment:下次执行时间"`
|
||||
TaskType int `json:"taskType" gorm:"column:taskType;comment:任务类型 0:cron 1:时间间隔"`
|
||||
}
|
||||
|
||||
// TableName TaskInfo's table name
|
||||
func (*TaskInfo) TableName() string {
|
||||
return TableNameTaskInfo
|
||||
}
|
||||
|
||||
// GroupName TaskInfo's table group
|
||||
func (*TaskInfo) GroupName() string {
|
||||
return "default"
|
||||
}
|
||||
|
||||
// NewTaskInfo create a new TaskInfo
|
||||
func NewTaskInfo() *TaskInfo {
|
||||
return &TaskInfo{
|
||||
Model: cool.NewModel(),
|
||||
}
|
||||
}
|
||||
|
||||
// init 创建表
|
||||
func init() {
|
||||
cool.CreateTable(&TaskInfo{})
|
||||
}
|
||||
37
modules/task/model/task_log.go
Normal file
37
modules/task/model/task_log.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/cool-team-official/cool-admin-go/cool"
|
||||
)
|
||||
|
||||
const TableNameTaskLog = "task_log"
|
||||
|
||||
// TaskLog mapped from table <task_log>
|
||||
type TaskLog struct {
|
||||
*cool.Model
|
||||
TaskId uint64 `gorm:"column:taskId;comment:任务ID" json:"taskId"`
|
||||
Status uint8 `gorm:"column:status;not null;comment:状态 0:失败 1:成功" json:"status"`
|
||||
Detail string `gorm:"column:detail;comment:详情" json:"detail"`
|
||||
}
|
||||
|
||||
// TableName TaskLog's table name
|
||||
func (*TaskLog) TableName() string {
|
||||
return TableNameTaskLog
|
||||
}
|
||||
|
||||
// GroupName TaskLog's table group
|
||||
func (*TaskLog) GroupName() string {
|
||||
return "default"
|
||||
}
|
||||
|
||||
// NewTaskLog create a new TaskLog
|
||||
func NewTaskLog() *TaskLog {
|
||||
return &TaskLog{
|
||||
Model: cool.NewModel(),
|
||||
}
|
||||
}
|
||||
|
||||
// init 创建表
|
||||
func init() {
|
||||
cool.CreateTable(&TaskLog{})
|
||||
}
|
||||
9
modules/task/packed/packed.go
Normal file
9
modules/task/packed/packed.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package packed
|
||||
|
||||
import "github.com/gogf/gf/v2/os/gres"
|
||||
|
||||
func init() {
|
||||
if err := gres.Add("H4sIAAAAAAAC/wrwZmYRYeBgYGDYGxccyoAE5Bg4GXLzU0pzUov1SxKLs/WLUovzS4uSU/Uz8zJLsorz80JDWBkYw576Jwd4s3Mga4UZysFwHM1QXYKGgoXjM/PS8vXgdqQ/9U8umXjWy9hQpO17sWh7ZO38CM+grhlLRR0LVO92nthoOXXjZR/PcyLdO0ICWFjFS6MDjrTuENWqMPZ7nepR37ZNeVLovD17/P02yTPMYWVgSExx4l3IE7789i7llFWuulLJqlO0PAMnSStc37omIzBO2OnJwy25/3i0l2oXGeZoqKkVd8hkbciUOf/Ds2hL8rSJi80Uw4VvRzwTW77s4e+jL94V3ag+ZVf9uVu9zIhTQ+PwqYqn7oVXuriCXk14LbZUt+Ss59/bud9+KJ2K0tB98uHVz931xqF9du82X29ff1Bh97vnb+dNDJbPmlD8oIJ7JpdXdp1zc8/pI5Nfu3w9OWP2i0zrrV+zfF6UTX5cz9tj+/f80Tu5/clK9TJWT/deOVeXvHDiRfPszTkMBXIyf1gYGP7/B0XFYkkJG3VGBob/jLCoAIHzaFEhhjMqwGFeBo5XWOJA1yyKSzOSXuxpAtMsHjSzyDCCHWEEHt2MTCLMuNM6BAgwvHUE0USnfJihkLSOHPS6cEMZGJY0hhI0FFfKh9mBKxJhDv/v+ICRgXCUIkIBW6QiDJNlYiAYxbjN4kExKxPNLKKMYEcxYg3CCCTdrGwgeTYGNobLjAwMr5hAPEAAAAD//+HOjP3TBAAA"); err != nil {
|
||||
panic("add binary content to resource manager failed: " + err.Error())
|
||||
}
|
||||
}
|
||||
23
modules/task/resource/initjson/task_info.json
Normal file
23
modules/task/resource/initjson/task_info.json
Normal file
@@ -0,0 +1,23 @@
|
||||
[
|
||||
{
|
||||
"id": "1",
|
||||
"createTime": "2022-10-19 17:15:03.000",
|
||||
"updateTime": "2022-10-19 17:22:51.000",
|
||||
"deleted_at": null,
|
||||
"jobId": null,
|
||||
"repeatConf": null,
|
||||
"name": "清理日志",
|
||||
"cron": "1 2 3 * * *",
|
||||
"limit": null,
|
||||
"every": null,
|
||||
"remark": "每天03:02:01执行清理缓存任务",
|
||||
"status": 1,
|
||||
"startDate": null,
|
||||
"endDate": null,
|
||||
"data": null,
|
||||
"service": "BaseFuncClearLog(false)",
|
||||
"type": 0,
|
||||
"nextRunTime": null,
|
||||
"taskType": 0
|
||||
}
|
||||
]
|
||||
63
modules/task/service/service.go
Normal file
63
modules/task/service/service.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/cool-team-official/cool-admin-go/cool"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gcron"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
)
|
||||
|
||||
// EnableTask 启用任务
|
||||
func EnableTask(ctx g.Ctx, cronId string, funcstring string, cron string, startDate string) (err error) {
|
||||
funcName := gstr.SubStr(funcstring, 0, gstr.Pos(funcstring, "("))
|
||||
if _, ok := cool.FuncMap[funcName]; !ok {
|
||||
err = gerror.New("函数不存在" + funcName)
|
||||
return
|
||||
}
|
||||
taskInfoService := NewTaskInfoService()
|
||||
|
||||
if cool.FuncMap[funcName].IsSingleton() {
|
||||
gcron.Remove(cronId)
|
||||
_, err = gcron.AddSingleton(ctx, cron, func(ctx g.Ctx) {
|
||||
nowDate := gtime.Now().Format("Y-m-d H:i:s")
|
||||
if nowDate < startDate {
|
||||
g.Log().Debug(ctx, "当前时间小于启用时间, 不执行单例函数", funcName)
|
||||
return
|
||||
}
|
||||
err := cool.RunFunc(ctx, funcstring)
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, err)
|
||||
taskInfoService.Record(ctx, cronId, 0, err.Error())
|
||||
} else {
|
||||
taskInfoService.Record(ctx, cronId, 1, "任务执行成功")
|
||||
}
|
||||
}, cronId)
|
||||
} else {
|
||||
gcron.Remove(cronId)
|
||||
_, err = gcron.Add(ctx, cron, func(ctx g.Ctx) {
|
||||
nowDate := gtime.Now().Format("Y-m-d H:i:s")
|
||||
if nowDate < startDate {
|
||||
g.Log().Debug(ctx, "当前时间小于启用时间, 不执行函数", funcName)
|
||||
return
|
||||
}
|
||||
err := cool.RunFunc(ctx, funcstring)
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, err)
|
||||
taskInfoService.Record(ctx, cronId, 0, gstr.AddSlashes(err.Error()))
|
||||
} else {
|
||||
taskInfoService.Record(ctx, cronId, 1, gstr.AddSlashes("任务执行成功"))
|
||||
}
|
||||
taskInfoService.SetNextRunTime(ctx, cronId, cron)
|
||||
}, cronId)
|
||||
}
|
||||
taskInfoService.SetNextRunTime(ctx, cronId, cron)
|
||||
return
|
||||
}
|
||||
|
||||
// DisableTask 禁用任务
|
||||
func DisableTask(ctx g.Ctx, cronId string) (err error) {
|
||||
gcron.Remove(cronId)
|
||||
return
|
||||
}
|
||||
185
modules/task/service/task_info.go
Normal file
185
modules/task/service/task_info.go
Normal file
@@ -0,0 +1,185 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/cool-team-official/cool-admin-go/cool"
|
||||
"github.com/cool-team-official/cool-admin-go/modules/task/model"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/robfig/cron"
|
||||
)
|
||||
|
||||
type TaskInfoService struct {
|
||||
*cool.Service
|
||||
}
|
||||
|
||||
func NewTaskInfoService() *TaskInfoService {
|
||||
return &TaskInfoService{
|
||||
&cool.Service{
|
||||
Model: model.NewTaskInfo(),
|
||||
PageQueryOp: &cool.QueryOp{
|
||||
FieldEQ: []string{"status", "type"},
|
||||
},
|
||||
UniqueKey: map[string]string{
|
||||
"name": "任务名称不能重复",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *TaskInfoService) ModifyAfter(ctx g.Ctx, method string, param g.MapStrAny) (err error) {
|
||||
g.Log().Info(ctx, "TaskInfoService.ModifyAfter", method, param)
|
||||
if method == "Add" {
|
||||
if gconv.Int(param["status"]) == 1 {
|
||||
id, err := cool.DBM(s.Model).Where("name = ?", param["name"]).Value("id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cool.ClusterRunFunc(ctx, "TaskAddTask("+id.String()+")")
|
||||
}
|
||||
}
|
||||
if method == "Update" {
|
||||
id := gconv.String(param["id"])
|
||||
if gconv.Int(param["status"]) == 1 {
|
||||
return cool.ClusterRunFunc(ctx, "TaskStartFunc("+id+")")
|
||||
} else {
|
||||
return cool.ClusterRunFunc(ctx, "TaskStopFunc("+id+")")
|
||||
}
|
||||
}
|
||||
if method == "Delete" {
|
||||
id := gconv.String(param["id"])
|
||||
return cool.ClusterRunFunc(ctx, "TaskStopFunc("+id+")")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Record 保存任务记录,成功任务每个任务保留最新20条日志,失败日志不会删除
|
||||
func (s *TaskInfoService) Record(ctx g.Ctx, id string, status int, detail string) error {
|
||||
taskLog := model.NewTaskLog()
|
||||
_, err := cool.DBM(taskLog).Data(g.Map{
|
||||
"taskId": id,
|
||||
"status": status,
|
||||
"detail": detail,
|
||||
}).Insert()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if status == 1 {
|
||||
record, err := cool.DBM(taskLog).Where("taskId = ?", id).Where("status", 1).Order("id", "desc").Offset(19).One()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if record.IsEmpty() {
|
||||
return nil
|
||||
}
|
||||
minId := record["id"].Int()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = cool.DBM(taskLog).Where("taskId = ?", id).Where("status", 1).Where("id < ?", minId).Delete()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Once 执行一次任务
|
||||
func (s *TaskInfoService) Once(ctx g.Ctx, id int64) error {
|
||||
record, err := cool.DBM(s.Model).Where("id = ?", id).One()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if record.IsEmpty() {
|
||||
return gerror.New("任务不存在")
|
||||
}
|
||||
funcString := record["service"].String()
|
||||
return cool.ClusterRunFunc(ctx, funcString)
|
||||
}
|
||||
|
||||
// Log 获取任务日志
|
||||
func (s *TaskInfoService) Log(ctx g.Ctx, param g.MapStrStr) (data interface{}, err error) {
|
||||
var (
|
||||
Total = 0
|
||||
Page = 1
|
||||
Size = 10
|
||||
)
|
||||
taskLog := model.NewTaskLog()
|
||||
m := cool.DBM(taskLog).LeftJoin("task_info", "task_info.id = task_log.taskId")
|
||||
|
||||
if id, ok := param["id"]; ok {
|
||||
m = m.Where("taskId = ?", id)
|
||||
}
|
||||
if status, ok := param["status"]; ok {
|
||||
m = m.Where("status = ?", status)
|
||||
}
|
||||
Total, err = m.Clone().Count()
|
||||
m = m.Fields("task_log.*,task_info.name as taskName")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if page, ok := param["page"]; ok {
|
||||
Page = gconv.Int(page)
|
||||
|
||||
}
|
||||
if size, ok := param["size"]; ok {
|
||||
Size = gconv.Int(size)
|
||||
}
|
||||
m = m.Limit(Size).Offset((Page - 1) * Size)
|
||||
|
||||
result, err := m.Order("id", "desc").All()
|
||||
// g.Dump(result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if result.IsEmpty() {
|
||||
return g.Map{
|
||||
"list": g.Slice{},
|
||||
"pagination": g.Map{
|
||||
"total": Total,
|
||||
"size": Size,
|
||||
"page": Page,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
// g.Log().Info(ctx, "TaskInfoService.Log", result)
|
||||
data = g.Map{
|
||||
"list": result,
|
||||
"pagination": g.Map{
|
||||
"total": Total,
|
||||
"size": Size,
|
||||
"page": Page,
|
||||
},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SetNextRunTime 更新下次执行时间
|
||||
func (s *TaskInfoService) SetNextRunTime(ctx g.Ctx, cronId string, cron string) error {
|
||||
// 更新下次执行时间
|
||||
nextTime, e := getCronNextTime(cron, time.Now())
|
||||
|
||||
if e == nil {
|
||||
_, err := cool.DBM(s.Model).Where("id = ?", cronId).Data("nextRunTime", nextTime).Update()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
g.Log().Debug(ctx, "获取下次执行时间失败", e)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getCronNextTime 获取下一次Cron的执行时间
|
||||
func getCronNextTime(cronStr string, t time.Time) (nextTime time.Time, err error) {
|
||||
p := cron.NewParser(cron.Second | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor)
|
||||
s, err := p.Parse(cronStr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
nextTime = s.Next(t)
|
||||
return
|
||||
}
|
||||
33
modules/task/task.go
Normal file
33
modules/task/task.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package demo
|
||||
|
||||
import (
|
||||
_ "github.com/cool-team-official/cool-admin-go/modules/task/packed"
|
||||
|
||||
"github.com/cool-team-official/cool-admin-go/cool"
|
||||
_ "github.com/cool-team-official/cool-admin-go/modules/task/controller"
|
||||
_ "github.com/cool-team-official/cool-admin-go/modules/task/funcs"
|
||||
_ "github.com/cool-team-official/cool-admin-go/modules/task/middleware"
|
||||
"github.com/cool-team-official/cool-admin-go/modules/task/model"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
)
|
||||
|
||||
func init() {
|
||||
var (
|
||||
taskInfo = model.NewTaskInfo()
|
||||
ctx = gctx.GetInitCtx()
|
||||
)
|
||||
g.Log().Debug(ctx, "module task init start ...")
|
||||
cool.FillInitData(ctx, "task", taskInfo)
|
||||
|
||||
result, err := cool.DBM(taskInfo).Where("status = ?", 1).All()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range result {
|
||||
id := v["id"].String()
|
||||
cool.RunFunc(ctx, "TaskAddTask("+id+")")
|
||||
}
|
||||
g.Log().Debug(ctx, "module task init finished ...")
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user