Files
yunzerwebsiteallinone/go/controllers/api_reminder.go
T
2026-07-20 11:41:39 +08:00

169 lines
4.7 KiB
Go

package controllers
import (
"time"
"server/models"
beego "github.com/beego/beego/v2/server/web"
)
type ApiReminderController struct {
beego.Controller
}
// AckReminder GET /api/schedule/reminder/ack
// 邮件/Bark 客户端访问此接口进行提醒确认。
// backend 与 platform 使用各自的提醒表,这里按 token 自动识别来源。
func (c *ApiReminderController) AckReminder() {
token := c.GetString("token")
if token == "" {
c.Ctx.Output.SetStatus(400)
_ = c.Ctx.Output.Body([]byte("Invalid request: missing token"))
return
}
type reminderState struct {
AckStatus int8
ScheduleID uint64
RemindStatus int8
}
var state reminderState
table := ""
var backendReminder models.BackendScheduleReminder
if err := models.Orm.QueryTable(new(models.BackendScheduleReminder)).
Filter("ack_token", token).
Filter("is_deleted", 0).
One(&backendReminder); err == nil {
state = reminderState{
AckStatus: backendReminder.AckStatus,
ScheduleID: backendReminder.ScheduleID,
RemindStatus: backendReminder.RemindStatus,
}
table = "backend"
} else {
var platformReminder models.PlatformScheduleReminder
if err := models.Orm.QueryTable(new(models.PlatformScheduleReminder)).
Filter("ack_token", token).
Filter("is_deleted", 0).
One(&platformReminder); err != nil {
c.Ctx.Output.SetStatus(404)
_ = c.Ctx.Output.Body([]byte("Error: reminder task not found or token has expired"))
return
}
state = reminderState{
AckStatus: platformReminder.AckStatus,
ScheduleID: platformReminder.ScheduleID,
RemindStatus: platformReminder.RemindStatus,
}
table = "platform"
}
if state.AckStatus == 1 {
writeReminderAckAlreadyConfirmed(c)
return
}
now := time.Now()
var err error
if table == "backend" {
_, err = models.Orm.QueryTable(new(models.BackendScheduleReminder)).
Filter("ack_token", token).
Filter("is_deleted", 0).
Update(map[string]interface{}{
"AckStatus": int8(1),
"AckTime": now,
"RemindStatus": int8(2),
"UpdateTime": now,
})
} else {
_, err = models.Orm.QueryTable(new(models.PlatformScheduleReminder)).
Filter("ack_token", token).
Filter("is_deleted", 0).
Update(map[string]interface{}{
"AckStatus": int8(1),
"AckTime": now,
"RemindStatus": int8(2),
"UpdateTime": now,
})
}
if err != nil {
c.Ctx.Output.SetStatus(500)
_ = c.Ctx.Output.Body([]byte("Database error, please try again later"))
return
}
// 只关闭命中来源表中、同一日程的其他待提醒记录,避免两套表互相影响。
if table == "backend" {
_, _ = models.Orm.QueryTable(new(models.BackendScheduleReminder)).
Filter("schedule_id", state.ScheduleID).
Filter("remind_status__in", 0, 1).
Update(map[string]interface{}{
"RemindStatus": int8(2),
"UpdateTime": now,
})
} else {
_, _ = models.Orm.QueryTable(new(models.PlatformScheduleReminder)).
Filter("schedule_id", state.ScheduleID).
Filter("remind_status__in", 0, 1).
Update(map[string]interface{}{
"RemindStatus": int8(2),
"UpdateTime": now,
})
}
writeReminderAckSuccess(c)
}
func writeReminderAckAlreadyConfirmed(c *ApiReminderController) {
c.Ctx.Output.Header("Content-Type", "text/html; charset=utf-8")
_ = c.Ctx.Output.Body([]byte(`
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>确认收到提醒</title>
<style>
body { font-family: sans-serif; text-align: center; padding: 50px; background: #f5f7fa; color: #303133; }
.card { background: white; padding: 40px; border-radius: 8px; box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1); display: inline-block; max-width: 400px; }
h2 { color: #67C23A; }
</style>
</head>
<body>
<div class="card">
<h2>提示</h2>
<p>该日程提醒在此之前已确认过了。</p>
<p style="color: #909399; font-size: 14px;">无需重复点击,感谢您的使用!</p>
</div>
</body>
</html>
`))
}
func writeReminderAckSuccess(c *ApiReminderController) {
c.Ctx.Output.Header("Content-Type", "text/html; charset=utf-8")
_ = c.Ctx.Output.Body([]byte(`
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>确认成功</title>
<style>
body { font-family: sans-serif; text-align: center; padding: 50px; background: #f5f7fa; color: #303133; }
.card { background: white; padding: 40px; border-radius: 8px; box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1); display: inline-block; max-width: 400px; }
h2 { color: #67C23A; }
</style>
</head>
<body>
<div class="card">
<h2>确认成功</h2>
<p>您已成功确认收到该日程提醒!</p>
<p style="color: #909399; font-size: 14px;">系统已停止向您重复推送,感谢您的配合。</p>
</div>
</body>
</html>
`))
}