修复日程提醒功能
This commit is contained in:
+168
-109
@@ -1,109 +1,168 @@
|
||||
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 客户端访问此接口进行提醒确认
|
||||
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
|
||||
}
|
||||
|
||||
var reminder models.PlatformScheduleReminder
|
||||
err := models.Orm.QueryTable(new(models.PlatformScheduleReminder)).
|
||||
Filter("ack_token", token).
|
||||
Filter("is_deleted", 0).
|
||||
One(&reminder)
|
||||
if err != nil {
|
||||
c.Ctx.Output.SetStatus(404)
|
||||
_ = c.Ctx.Output.Body([]byte("Error: reminder task not found or token has expired"))
|
||||
return
|
||||
}
|
||||
|
||||
if reminder.AckStatus == 1 {
|
||||
// 已经确认过了,直接显示已确认成功的 HTML
|
||||
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>
|
||||
`))
|
||||
return
|
||||
}
|
||||
|
||||
// 更新确认状态为已确认,置 remind_status 为已结束(2)
|
||||
now := time.Now()
|
||||
reminder.AckStatus = 1
|
||||
reminder.AckTime = &now
|
||||
reminder.RemindStatus = 2
|
||||
reminder.UpdateTime = now
|
||||
|
||||
_, err = models.Orm.Update(&reminder, "AckStatus", "AckTime", "RemindStatus", "UpdateTime")
|
||||
if err != nil {
|
||||
c.Ctx.Output.SetStatus(500)
|
||||
_ = c.Ctx.Output.Body([]byte("Database error, please try again later"))
|
||||
return
|
||||
}
|
||||
|
||||
// 统一关闭该日程下的所有其他待提醒/提醒中渠道,防止重复打扰
|
||||
_, _ = models.Orm.QueryTable(new(models.PlatformScheduleReminder)).
|
||||
Filter("ScheduleID", reminder.ScheduleID).
|
||||
Filter("RemindStatus__in", 0, 1).
|
||||
Update(map[string]interface{}{
|
||||
"RemindStatus": int8(2),
|
||||
"UpdateTime": now,
|
||||
})
|
||||
|
||||
// 成功确认
|
||||
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>
|
||||
`))
|
||||
}
|
||||
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>
|
||||
`))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user