| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399 |
- package core
- import (
- "encoding/json"
- "fmt"
- "regexp"
- "sort"
- "time"
- "github.com/cdle/sillyplus/core/common"
- "github.com/cdle/sillyplus/core/storage"
- "github.com/cdle/sillyplus/utils"
- "github.com/gin-gonic/gin"
- "github.com/robfig/cron/v3"
- )
- var tasks = MakeBucket("tasks")
- type TasksResult struct {
- Success bool `json:"success"`
- Data []*Tasks `json:"data"`
- Page int `json:"page"`
- Total int `json:"total"`
- Time time.Time `json:"time"`
- }
- type Sender struct {
- ChatID string `json:"chat_id"`
- UserID string `json:"user_id"`
- Platfrom string `json:"platform"`
- BotID string `json:"bot_id"`
- }
- type Tasks struct {
- Index int `json:"id"` //编号 顺序编号
- ID string `json:"task_id"` //任务ID
- Title string `json:"title"` //任务名
- Schedule string `json:"schedule"` //计划时间
- Senders []Sender `json:"senders"` //发送人
- Command string `json:"command"` //消息指令
- Scripts []string `json:"scripts"` //触发脚本
- CronID int `json:"cron_id"`
- CreatedAt int `json:"created_at"` //创建时间戳(秒)转换成日期
- Remark string `json:"remark"`
- Enable bool `json:"enable"`
- Handle func() `json:"-"`
- Icons []interface{} `json:"icons"`
- }
- var pts = []*Tasks{}
- func RegistTasks(pt *Tasks) {
- pt.Handle = func() {
- content := pt.Command
- for _, meta := range pt.Senders {
- adapter, _ := GetAdapter(meta.Platfrom, meta.BotID)
- if adapter != nil {
- sender := adapter.Sender2(nil)
- sender.SetFsps(&common.FakerSenderParams{
- Content: content,
- ChatID: meta.ChatID,
- UserID: meta.UserID,
- })
- for _, script := range pt.Scripts {
- for _, function := range Functions {
- if function.UUID == script {
- for i := range function.Rules {
- reg, err := regexp.Compile(function.Rules[i])
- if err == nil {
- if res := reg.FindStringSubmatch(content); len(res) > 0 {
- sender.SetMatch(res[1:])
- sender.SetParams(function.Params[i])
- }
- }
- }
- function.Handle(sender, nil)
- break
- }
- }
- }
- }
- }
- }
- cid, _ := CRON.AddFunc(pt.Schedule, pt.Handle)
- pt.CronID = int(cid)
- // console.Debug("已添加计划任务:%s(%v)", pt.Title, pt.CronID)
- }
- func init() {
- tasks.Foreach(func(b1, b2 []byte) error {
- pt := Tasks{}
- err := json.Unmarshal(b2, &pt)
- if err != nil {
- return nil
- }
- RegistTasks(&pt)
- pts = append(pts, &pt)
- return nil
- })
- sort.Sort(byCreatedAt2(pts))
- for i := range pts {
- pts[i].Index = i + 1
- }
- storage.Watch(tasks, nil, func(old, new, key string) *storage.Final {
- console.Log("已更新计划任务")
- ocg := Tasks{}
- ncg := Tasks{}
- json.Unmarshal([]byte(old), &ocg)
- json.Unmarshal([]byte(new), &ncg)
- tmp := pts
- if old != "" {
- if new == "" { // 删除
- if ocg.ID != "" {
- for i, cg := range tmp {
- if cg.ID == ocg.ID {
- CRON.Remove(cron.EntryID(tmp[i].CronID))
- tmp = append(tmp[:i], tmp[i+1:]...)
- break
- }
- }
- } else {
- return nil
- }
- } else { // 修改
- if ocg.ID != "" {
- for i, cg := range tmp {
- if cg.ID == ocg.ID {
- CRON.Remove(cron.EntryID(tmp[i].CronID))
- tmp[i] = &ncg
- RegistTasks(&ncg)
- //todo 增
- break
- }
- }
- } else {
- return nil
- }
- }
- } else { //创建
- if ncg.ID != "" {
- tmp = append(tmp, &ncg)
- RegistTasks(&ncg)
- //todo 增
- } else {
- return nil
- }
- }
- sort.Sort(byCreatedAt2(pts))
- for i := range tmp {
- tmp[i].Index = i + 1
- }
- pts = tmp
- return nil
- })
- GinApi(GET, "/api/tasks", RequireAuth, func(ctx *gin.Context) {
- current := utils.Int(ctx.Query("current"))
- pageSize := utils.Int(ctx.Query("pageSize"))
- rr := TasksResult{
- Success: true,
- }
- pts := pts
- rr.Total = len(pts)
- if current == 0 {
- current = 1
- }
- if pageSize == 0 {
- pageSize = 20
- }
- begin := (current - 1) * pageSize
- end := (current) * pageSize
- if end > rr.Total {
- end = rr.Total
- }
- if begin > end {
- begin = end
- }
- rr.Data = pts[begin:end]
- for i := range rr.Data {
- rr.Data[i].Icons = []interface{}{}
- for _, script := range rr.Data[i].Scripts {
- for _, f := range Functions {
- if f.UUID == script {
- if f.Icon != "" {
- rr.Data[i].Icons = append(rr.Data[i].Icons, map[string]interface{}{
- "link": f.Icon,
- "title": f.Title,
- })
- break
- }
- }
- }
- }
- }
- ctx.JSON(200, rr)
- })
- GinApi(POST, "/api/tasks", RequireAuth, func(ctx *gin.Context) {
- // 将请求的 JSON 数据解析为一个 map[string]interface{} 类型的变量
- var updateData map[string]interface{}
- err := ctx.BindJSON(&updateData)
- if err != nil {
- ctx.JSON(200, map[string]interface{}{
- "success": false,
- "errorMessage": err.Error(),
- })
- return
- }
- v, ok := updateData["task_id"]
- if !ok {
- ctx.JSON(200, map[string]interface{}{
- "success": false,
- "errorMessage": "任务ID不能为空",
- })
- return
- }
- task_id := v.(string)
- var tp = Tasks{
- ID: task_id,
- }
- tasks.First(&tp)
- for key, value := range updateData {
- switch key {
- case "title":
- if v, ok := value.(string); ok {
- tp.Title = v
- }
- case "remark":
- if v, ok := value.(string); ok {
- tp.Remark = v
- }
- case "schedule":
- if v, ok := value.(string); ok {
- tp.Schedule = v
- id, err := CRON.AddFunc(tp.Schedule, func() {})
- if err != nil {
- ctx.JSON(200, map[string]interface{}{
- "success": false,
- "errorMessage": "Cron表达式错误:" + err.Error(),
- })
- return
- }
- CRON.Remove(id)
- }
- case "senders":
- ss := []Sender{}
- err := json.Unmarshal(utils.JsonMarshal(value), &ss)
- if err != nil {
- ctx.JSON(200, map[string]interface{}{
- "success": false,
- "errorMessage": "Senders错误:" + err.Error(),
- })
- return
- }
- tp.Senders = ss
- case "command":
- if v, ok := value.(string); ok {
- tp.Command = v
- }
- case "scripts":
- if v, ok := value.([]interface{}); ok {
- tp.Scripts = toStringSlice(v)
- }
- case "enable":
- if v, ok := value.(bool); ok {
- tp.Enable = v
- }
- }
- }
- if tp.CreatedAt == 0 {
- tp.CreatedAt = int(time.Now().Unix())
- }
- tasks.Set(task_id, utils.JsonMarshal(tp))
- if err != nil {
- ctx.JSON(200, map[string]interface{}{
- "success": false,
- "errorMessage": err.Error(),
- })
- return
- }
- ctx.JSON(200, map[string]interface{}{
- "success": true,
- })
- })
- GinApi(DELETE, "/api/tasks", RequireAuth, func(ctx *gin.Context) {
- pt := &Tasks{}
- err := ctx.BindJSON(pt)
- if err != nil {
- ctx.JSON(200, map[string]interface{}{
- "success": false,
- "errorMessage": err.Error(),
- })
- return
- }
- if pt.ID == "" {
- ctx.JSON(200, map[string]interface{}{
- "success": false,
- "errorMessage": "任务ID不为空",
- })
- return
- }
- tasks.Set(pt.ID, "")
- ctx.JSON(200, map[string]interface{}{
- "success": true,
- })
- })
- GinApi(GET, "/api/task/selects", RequireAuth, func(ctx *gin.Context) {
- var scripts = map[string]string{}
- var task_id = ctx.Query("task_id")
- var pts = pts
- var chat_ids = []string{}
- var user_ids = []string{}
- for _, pt := range pts {
- if pt.ID == task_id {
- for _, s := range pt.Senders {
- if s.ChatID != "" {
- chat_ids = append(chat_ids, s.ChatID)
- }
- if s.UserID != "" {
- user_ids = append(user_ids, s.UserID)
- }
- }
- break
- }
- }
- functions := Functions
- for _, function := range functions {
- if function.UUID != "" {
- scripts[function.UUID] = function.Title + function.Suffix
- }
- }
- var user_names = []NicklabeL{}
- var group_names = []NicklabeL{{
- Label: "私聊",
- Value: "",
- }}
- nickname.Foreach(func(b1, b2 []byte) error {
- v := &Nickname{}
- code := string(b1)
- err := json.Unmarshal(b2, v)
- if err == nil {
- if v.Group {
- if Contains(chat_ids, code) {
- group_names = append(group_names, NicklabeL{
- Label: fmt.Sprintf("%s(%s)", v.Value, code),
- Value: code,
- })
- }
- } else {
- if Contains(user_ids, code) {
- user_names = append(user_names, NicklabeL{
- Label: fmt.Sprintf("%s(%s)", v.Value, code),
- Value: code,
- })
- }
- }
- }
- return nil
- })
- platforms := map[string][]string{}
- for _, plt := range getPltsArray() {
- platforms[plt] = GetAdapterBotsID(plt)
- }
- ctx.JSON(200, map[string]interface{}{
- "success": true,
- "data": map[string]interface{}{
- "scripts": scripts,
- "platforms": platforms,
- "user_names": user_names,
- "group_names": group_names,
- },
- })
- })
- GinApi(GET, "/api/tasks/run", RequireAuth, func(ctx *gin.Context) {
- var task_id = ctx.Query("task_id")
- for _, pt := range pts {
- if pt.ID == task_id {
- pt.Handle()
- }
- }
- ctx.JSON(200, map[string]interface{}{
- "success": true,
- })
- })
- }
- type byCreatedAt2 []*Tasks
- func (s byCreatedAt2) Len() int {
- return len(s)
- }
- func (s byCreatedAt2) Less(i, j int) bool {
- return s[i].CreatedAt > s[j].CreatedAt
- }
- func (s byCreatedAt2) Swap(i, j int) {
- s[i], s[j] = s[j], s[i]
- }
|