优化卡片

This commit is contained in:
hero920103 committed 2026-11-05 01:08:55 +08:00
1 parent e34543465a
commit 8acbe732ff
8 files changed
+181 -21

No files matched your search

+1 -1
View File
@@ -1,4 +1,4 @@
appname = server
appname = server
httpport = 9000
runmode = dev
+8 -6
View File
@@ -287,7 +287,7 @@ func (c *BackendReminderController) CreateReminder() {
for _, ch := range p.RemindChannels {
ch = strings.ToUpper(strings.TrimSpace(ch))
if ch != "SMS" && ch != "EMAIL" && ch != "BARK" && ch != "SITE_MSG" {
if ch != "SMS" && ch != "EMAIL" && ch != "BARK" && ch != "SITE_MSG" && ch != "WECHAT_MP" && ch != "WECHAT_MINI" {
continue
}
@@ -426,7 +426,7 @@ func (c *BackendReminderController) UpdateReminder() {
for _, ch := range p.RemindChannels {
ch = strings.ToUpper(strings.TrimSpace(ch))
if ch != "SMS" && ch != "EMAIL" && ch != "BARK" && ch != "SITE_MSG" {
if ch != "SMS" && ch != "EMAIL" && ch != "BARK" && ch != "SITE_MSG" && ch != "WECHAT_MP" && ch != "WECHAT_MINI" {
continue
}
@@ -691,10 +691,12 @@ func (c *BackendReminderController) TestReminder() {
}
senders := map[string]services.ReminderSender{
"SMS": &services.SMSSender{},
"EMAIL": &services.EmailSender{},
"BARK": &services.BarkSender{},
"SITE_MSG": &services.SiteMsgSender{},
"SMS": &services.SMSSender{},
"EMAIL": &services.EmailSender{},
"BARK": &services.BarkSender{},
"SITE_MSG": &services.SiteMsgSender{},
"WECHAT_MP": &services.WechatMpSender{},
"WECHAT_MINI": &services.WechatMiniSender{},
}
type TestResult struct {
+65 -5
View File
@@ -14,6 +14,7 @@ import (
"server/models"
"server/services/wechatmini"
"server/services/wechatmp"
"github.com/beego/beego/v2/core/logs"
)
@@ -312,6 +313,62 @@ func (s *SiteMsgSender) Send(ctx context.Context, reminder ReminderData, title,
return true, nil
}
// WechatMpSender 微信服务号模板消息发送实现
// 要求:服务号已认证且在平台设置中启用;用户已在服务号绑定账号并关注。
type WechatMpSender struct{}
func (s *WechatMpSender) Send(ctx context.Context, reminder ReminderData, title, content string) (bool, error) {
cfg, err := wechatmp.LoadEnabledConfig()
if err != nil {
return false, fmt.Errorf("服务号未配置或未启用: %w", err)
}
// 接收目标优先级:手动指定的 openid → 服务号粉丝绑定表反查
openid := ""
if reminder.ReceiverTarget != nil && *reminder.ReceiverTarget != "" {
openid = *reminder.ReceiverTarget
}
if openid == "" && reminder.Tid > 0 {
if f, ferr := wechatmp.GetFollowerByUser("tenant_user", reminder.ReceiverUserID); ferr == nil && f != nil {
if f.Subscribe != 1 {
return false, fmt.Errorf("用户已取消关注服务号,无法推送模板消息")
}
openid = f.OpenID
}
}
if openid == "" {
return false, fmt.Errorf("用户未绑定服务号,无法推送(请在服务号内完成账号绑定)")
}
perr := wechatmp.PushToOpenID(cfg, openid, wechatmp.PushMessage{
Title: title,
Content: content,
Remark: "来自云泽管理平台日程提醒",
})
if perr != nil {
return false, perr
}
return true, nil
}
// WechatMiniSender 微信小程序订阅消息发送实现
// 要求:用户在小程序内授权过订阅消息(一次性授权,发一条少一条)。
type WechatMiniSender struct{}
func (s *WechatMiniSender) Send(ctx context.Context, reminder ReminderData, title, content string) (bool, error) {
if reminder.ReceiverUserID == 0 {
return false, fmt.Errorf("无效的接收用户")
}
res := wechatmini.PushTenantNotice(reminder.ReceiverUserID, title, content)
if res.Sent > 0 {
return true, nil
}
if len(res.Errors) > 0 {
return false, res.Errors[0]
}
return false, fmt.Errorf("用户未授权小程序订阅消息(授权一次仅可发送一条)")
}
// generateUUID 生成一个安全的随机 UUID 字符
func generateUUID() string {
b := make([]byte, 16)
@@ -368,10 +425,12 @@ func scanAndSendReminders() {
// 实例分发发送
senders := map[string]ReminderSender{
"SMS": &SMSSender{},
"EMAIL": &EmailSender{},
"BARK": &BarkSender{},
"SITE_MSG": &SiteMsgSender{},
"SMS": &SMSSender{},
"EMAIL": &EmailSender{},
"BARK": &BarkSender{},
"SITE_MSG": &SiteMsgSender{},
"WECHAT_MP": &WechatMpSender{},
"WECHAT_MINI": &WechatMiniSender{},
}
for i := range list {
@@ -437,7 +496,8 @@ func scanAndSendReminders() {
newSendCount := reminder.SendCount + 1
newStatus := reminder.RemindStatus
if reminder.RemindChannel == "SMS" || reminder.RemindChannel == "SITE_MSG" {
if reminder.RemindChannel == "SMS" || reminder.RemindChannel == "SITE_MSG" ||
reminder.RemindChannel == "WECHAT_MP" || reminder.RemindChannel == "WECHAT_MINI" {
// 一次性发送:发送后直接置为结束
newStatus = 2
} else {