Skip to content

Commit 7769736

Browse files
committed
feat: 增加设置指定时间的一次性提醒任务
1 parent 793b435 commit 7769736

File tree

3 files changed

+74
-8
lines changed

3 files changed

+74
-8
lines changed

plugins/manager/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* `设置每周的提醒`,例如:设置每周三10:00:00的提醒
1313
* `设置每天的提醒`,例如:设置每天10:00:00的提醒
1414
* `设置每隔多久的提醒`,例如:设置每隔1小时的提醒
15+
* `设置指定时间的一次性提醒任务`,例如:设置2023-01-01 15:00:00的提醒
1516
* `列出所有任务`
1617
* `删除任务 任务ID`
1718
* `删除全部任务`

plugins/manager/cronjob.go

+61-8
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ const (
1717
JobTypeFunc = "func" // 函数类任务
1818
JobTypePlugin = "plugin" // 插件类任务
1919

20-
RegexOfRemindEveryMonth = `^设置每月(0?[1-9]|[12][0-9]|3[01])号(([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])的提醒$`
21-
RegexOfRemindEveryWeek = `^设置每周(一|二|三|四|五|六|七|日)(([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])的提醒$`
22-
RegexOfRemindEveryDay = `^设置每天(([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])的提醒$`
23-
RegexOfRemindInterval = `^设置每隔(\d+)(s|秒|m|分|分钟|h|时|d|小时)的提醒$`
20+
RegexOfRemindEveryMonth = `^设置每月(0?[1-9]|[12][0-9]|3[01])号(([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])的提醒$`
21+
RegexOfRemindEveryWeek = `^设置每周(一|二|三|四|五|六|七|日)(([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])的提醒$`
22+
RegexOfRemindEveryDay = `^设置每天(([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])的提醒$`
23+
RegexOfRemindInterval = `^设置每隔(\d+)(s|秒|m|分|分钟|h|时|d|小时)的提醒$`
24+
RegexOfRemindSpecifyTime = `^设置((20[2-9][0-9]|2100)-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])\s([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])的提醒$`
2425
)
2526

2627
type CronJob struct {
@@ -58,7 +59,7 @@ func registerCronjob() {
5859
if _, err := AddRemindOfEveryMonth(ctx, cronJob.Tag, matched, func() {
5960
ctx.SendText(cronJob.GroupId, cronJob.Remind)
6061
}); err != nil {
61-
log.Errorf("恢复每月提醒任务失败: jobId: %s, error: %v", cronJob.Id, err)
62+
log.Errorf("恢复每月提醒任务失败: jobId: %d, error: %v", cronJob.Id, err)
6263
}
6364
}
6465

@@ -67,7 +68,7 @@ func registerCronjob() {
6768
if _, err := AddRemindOfEveryWeek(ctx, cronJob.Tag, matched, func() {
6869
ctx.SendText(cronJob.GroupId, cronJob.Remind)
6970
}); err != nil {
70-
log.Errorf("恢复每周提醒任务失败: jobId: %s, error: %v", cronJob.Id, err)
71+
log.Errorf("恢复每周提醒任务失败: jobId: %d, error: %v", cronJob.Id, err)
7172
}
7273
}
7374

@@ -76,7 +77,7 @@ func registerCronjob() {
7677
if _, err := AddRemindOfEveryDay(ctx, cronJob.Tag, matched, func() {
7778
ctx.SendText(cronJob.GroupId, cronJob.Remind)
7879
}); err != nil {
79-
log.Errorf("恢复每天提醒任务失败: jobId: %s, error: %v", cronJob.Id, err)
80+
log.Errorf("恢复每天提醒任务失败: jobId: %d, error: %v", cronJob.Id, err)
8081
}
8182
}
8283

@@ -85,7 +86,16 @@ func registerCronjob() {
8586
if _, err := AddRemindForInterval(ctx, cronJob.Tag, matched, func() {
8687
ctx.SendText(cronJob.GroupId, cronJob.Remind)
8788
}); err != nil {
88-
log.Errorf("恢复间隔提醒任务失败: jobId: %s, error: %v", cronJob.Id, err)
89+
log.Errorf("恢复间隔提醒任务失败: jobId: %d, error: %v", cronJob.Id, err)
90+
}
91+
}
92+
93+
// 恢复指定时间提醒任务
94+
if matched := regexp.MustCompile(RegexOfRemindSpecifyTime).FindStringSubmatch(cronJob.Desc); matched != nil {
95+
if _, err := AddRemindForSpecifyTime(ctx, cronJob.Tag, matched, func() {
96+
ctx.SendText(cronJob.GroupId, cronJob.Remind)
97+
}); err != nil {
98+
log.Errorf("恢复指定时间提醒任务失败: jobId: %d, error: %v", cronJob.Id, err)
8999
}
90100
}
91101
}
@@ -265,6 +275,49 @@ func registerCronjob() {
265275
}
266276
})
267277

278+
// 设置指定时间的一次性提醒任务
279+
// 设置2023-01-01 15:00:00的提醒
280+
engine.OnRegex(RegexOfRemindSpecifyTime, robot.UserOrGroupAdmin).SetBlock(true).Handle(func(ctx *robot.Ctx) {
281+
matched := ctx.State["regex_matched"].([]string)
282+
jobDesc := ctx.MessageString()
283+
recv, cancel := ctx.EventChannel(ctx.CheckUserSession()).Repeat()
284+
defer cancel()
285+
ctx.ReplyText("请问需要提醒什么呢?")
286+
for {
287+
select {
288+
case <-time.After(20 * time.Second):
289+
ctx.ReplyTextAndAt("操作时间太久了,请重新设置")
290+
return
291+
case c := <-recv:
292+
jobId := mid.UniqueId()
293+
jobTag := strconv.Itoa(int(jobId))
294+
remind := c.Event.Message.Content
295+
296+
// 设置定时任务
297+
if _, err := AddRemindForSpecifyTime(ctx, jobTag, matched, func() { ctx.ReplyText(remind) }); err != nil {
298+
ctx.ReplyText(fmt.Errorf("设置失败: %v", err).Error())
299+
return
300+
}
301+
302+
// 存起来便于服务启动恢复
303+
if err := db.Orm.Table("cronjob").Create(&CronJob{
304+
Id: jobId,
305+
Tag: jobTag,
306+
Type: JobTypeRemind,
307+
GroupId: ctx.Event.FromUniqueID,
308+
Desc: jobDesc,
309+
Remind: remind,
310+
}).Error; err != nil {
311+
ctx.ReplyTextAndAt(fmt.Errorf("设置失败: %v", err).Error())
312+
return
313+
}
314+
ctx.ReplyTextAndAt(fmt.Sprintf("已为您%s: %s", jobDesc, remind))
315+
job.StartAsync()
316+
return
317+
}
318+
}
319+
})
320+
268321
// 列出当前所有定时任务
269322
engine.OnFullMatch("列出所有任务").SetBlock(true).Handle(func(ctx *robot.Ctx) {
270323
var cronJobs []CronJob

plugins/manager/cronjob_add.go

+12
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,15 @@ func AddRemindForInterval(ctx *robot.Ctx, jobTag string, matched []string, f fun
6666
}
6767
return job.Tag(jobTag).Do(func() { f() })
6868
}
69+
70+
// AddRemindForSpecifyTime 添加指定时间提醒
71+
func AddRemindForSpecifyTime(ctx *robot.Ctx, jobTag string, matched []string, f func()) (*gocron.Job, error) {
72+
parseTime, _ := time.ParseInLocation("2006-01-02 15:04:05", matched[1], time.Local)
73+
if parseTime.Before(time.Now()) {
74+
return nil, fmt.Errorf("请不要设置过去的时间")
75+
}
76+
return job.Every(1).Tag(jobTag).LimitRunsTo(1).StartAt(parseTime).Do(func() {
77+
f()
78+
db.Orm.Table("cronjob").Where("tag = ?", jobTag).Delete(&CronJob{})
79+
})
80+
}

0 commit comments

Comments
 (0)