diff --git a/api/consts/notif_template.go b/api/consts/notif_template.go index ed680387..ea94102c 100644 --- a/api/consts/notif_template.go +++ b/api/consts/notif_template.go @@ -8,7 +8,11 @@ const ( Notif_Vas = 2 // 付费消息 ) const ( - SysNotifTemp_CancelNotif = -1 // 取消推送通知 + // 操作控制部分,这部分为控制操作,不作为模板使用 + SysNotifTemp_CancelNotif = -1 // 取消推送通知 + SysNotifTemp_SyncNotifBcstVersForUser = -2 // 同步用户广播版本号 + SysNotifTemp_SyncNotifBcstVersForStreamer = -3 // 同步主播广播版本号 + SysNotifTemp_FirstLogin = 1 // 首次登录 SysNotifTemp_StreamerPunished = 2 // 主播封禁 SysNotifTemp_StreamerPunishmentEnds = 3 // 主播封禁结束 @@ -37,7 +41,7 @@ const ( AudNotifTemp_WithdrawalInfoApplied = 112 // 主播提交了申请提现相关的资料 AudNotifTemp_WithdrawalInfoPassed = 113 // 运营后台操作了相关资料审核:通过 AudNotifTemp_WithdrawalInfoRejected = 114 // 运营后台操作了相关资料审核:拒绝 - AudNotifTemp_StreamerUpdated = 115 // 主播在编辑主页时,仅修改选项内容后提交 + AudNotifTemp_StreamerDirectlyUpdated = 115 // 主播在编辑主页时,仅修改选项内容后提交 AudNotifTemp_BioChangeApplied = 116 // 主播在编辑主页时,修改个性签名后提交 AudNotifTemp_BioPassed = 117 // 运营审核通过【个性签名】 AudNotifTemp_BioRejected = 118 // 运营审核拒绝【个性签名】 diff --git a/api/interfaces/notif_builder_handler.go b/api/interfaces/notif_builder_handler.go index fa80346a..9e5aa130 100644 --- a/api/interfaces/notif_builder_handler.go +++ b/api/interfaces/notif_builder_handler.go @@ -3,5 +3,5 @@ package interfaces import "github.com/gin-gonic/gin" type NotifBuilderHandler interface { - Handle(ctx *gin.Context, scene int64, args ...any) + Handle(ctx *gin.Context) func(scenes ...int64) func(args ...any) } diff --git a/app/mix/service/apiservice.go b/app/mix/service/apiservice.go index decd3730..cabbdac9 100644 --- a/app/mix/service/apiservice.go +++ b/app/mix/service/apiservice.go @@ -164,7 +164,8 @@ func (s *Service) ApiLoginByVeriCode(ctx *gin.Context, req *loginproto.ApiLoginB return } // 写入自动发送消息的标签 - DefaultNotifBuilderHandler.Handle(ctx, consts.SysNotifTemp_FirstLogin, account) + DefaultNotifBuilderHandler.Handle(ctx)( + consts.SysNotifTemp_FirstLogin, consts.SysNotifTemp_SyncNotifBcstVersForUser)(account) } else if ec != errcode.ErrCodeLoginSrvOk { return } @@ -328,7 +329,7 @@ func (s *Service) ApiUpdatePassword(ctx *gin.Context, req *loginproto.ApiUpdateP } // 4.发送通知 - DefaultNotifBuilderHandler.Handle(ctx, consts.SysNotifTemp_PswdChanged, login) + DefaultNotifBuilderHandler.Handle(ctx)(consts.SysNotifTemp_PswdChanged)(login) return } @@ -385,6 +386,8 @@ func (s *Service) ApiUpdateAccount(ctx *gin.Context, req *accountproto.ApiUpdate } } + // 发送通知 + return } @@ -649,7 +652,7 @@ func (s *Service) ApiCancelAccount(ctx *gin.Context, req *accountproto.ApiCancel } // 发送通知 - DefaultNotifBuilderHandler.Handle(ctx, consts.SysNotifTemp_AcctCancellationApplied, account) + DefaultNotifBuilderHandler.Handle(ctx)(consts.SysNotifTemp_AcctCancellationApplied)(account) return @@ -2755,7 +2758,7 @@ func (s *Service) ApiCreateZone(ctx *gin.Context, req *zoneproto.ApiCreateReq) ( } }() - DefaultNotifBuilderHandler.Handle(ctx, consts.SysNotifTemp_ZoneCreated, req.Zone) + DefaultNotifBuilderHandler.Handle(ctx)(consts.SysNotifTemp_ZoneCreated)(req.Zone) return } @@ -2815,7 +2818,7 @@ func (s *Service) ApiUpdateZone(ctx *gin.Context, req *zoneproto.ApiUpdateReq) ( s.CreateZoneTextAudit(ctx, oldZone, req.Zone) // 发送通知 - DefaultNotifBuilderHandler.Handle(ctx, consts.SysNotifTemp_ZoneVasUpdated, req) + DefaultNotifBuilderHandler.Handle(ctx)(consts.SysNotifTemp_ZoneVasUpdated)(req) return } @@ -3695,7 +3698,7 @@ func (s *Service) ApiCreateZoneThirdPartner(ctx *gin.Context, req *zone_third_pa } // 发送通知 - DefaultNotifBuilderHandler.Handle(ctx, consts.SysNotifTemp_ZoneThirdPartnerCreated, req.BaseRequest.Mid) + DefaultNotifBuilderHandler.Handle(ctx)(consts.SysNotifTemp_ZoneThirdPartnerCreated)(req.BaseRequest.Mid) return } diff --git a/app/mix/service/notif_builder_handler.go b/app/mix/service/notif_builder_handler.go index f8737fcc..e7192cbe 100644 --- a/app/mix/service/notif_builder_handler.go +++ b/app/mix/service/notif_builder_handler.go @@ -20,8 +20,14 @@ type NotifBuilderHandler struct { handlerMap map[int64]func(ctx *gin.Context, args ...any) } -func (handler *NotifBuilderHandler) Handle(ctx *gin.Context, scene int64, args ...any) { - handler.handlerMap[scene](ctx, args...) +func (handler *NotifBuilderHandler) Handle(ctx *gin.Context) func(scenes ...int64) func(args ...any) { + return func(scenes ...int64) func(args ...any) { + return func(args ...any) { + for _, scene := range scenes { + handler.handlerMap[scene](ctx, args...) + } + } + } } func NewNotifBuilderHandler() *NotifBuilderHandler { @@ -33,8 +39,11 @@ func NewNotifBuilderHandler() *NotifBuilderHandler { func (handler *NotifBuilderHandler) init() { handler.handlerMap = make(map[int64]func(ctx *gin.Context, args ...any)) handler.handleSysNotifCancelNotif() + handler.handleSyncNotifBcstVersForUser() + handler.handleSyncNotifBcstVersForStreamer() handler.handleSysFirstLogin() handler.handleSysStreamerPunished() + handler.handleSysStreamerPunishmentEnds() handler.handleSysPswdChanged() handler.handleSysAcctCancellationApplied() handler.handleSysStreamerAuthApprovalPassed() @@ -57,17 +66,37 @@ func (handler *NotifBuilderHandler) handleSysFirstLogin() { } } +func (handler *NotifBuilderHandler) handleSyncNotifBcstVersForUser() { + handler.handlerMap[consts.SysNotifTemp_SyncNotifBcstVersForUser] = func(ctx *gin.Context, args ...any) { + account := args[0].(*dbstruct.Account) + DefaultService.utilWriteNotifInfo(ctx, consts.SysNotifTemp_SyncNotifBcstVersForUser, account.GetMid()) + } +} + +func (handler *NotifBuilderHandler) handleSyncNotifBcstVersForStreamer() { + handler.handlerMap[consts.SysNotifTemp_SyncNotifBcstVersForStreamer] = func(ctx *gin.Context, args ...any) { + account := args[0].(*dbstruct.Account) + DefaultService.utilWriteNotifInfo(ctx, consts.SysNotifTemp_SyncNotifBcstVersForStreamer, account.GetMid()) + } +} + func (handler *NotifBuilderHandler) handleSysStreamerPunished() { handler.handlerMap[consts.SysNotifTemp_StreamerPunished] = func(ctx *gin.Context, args ...any) { acctpunishment := args[0].(*dbstruct.AccountPunishment) // 封禁通知 DefaultService.utilWriteNotifInfo(ctx, consts.SysNotifTemp_StreamerPunished, acctpunishment.GetMid(), consts.AccountPunishmentMap[acctpunishment.GetType()], util.FormatTsAsNotifT(acctpunishment.GetEndTime())) + } +} + +func (handler *NotifBuilderHandler) handleSysStreamerPunishmentEnds() { + handler.handlerMap[consts.SysNotifTemp_StreamerPunishmentEnds] = func(ctx *gin.Context, args ...any) { + acctpunishment := args[0].(*dbstruct.AccountPunishment) // 解禁通知 if !acctpunishment.IsPermanent() { argsMap := make(map[string]any) argsMap["push_time"] = acctpunishment.GetEndTime() - argsMap["nid_save_func"] = func(ctx *gin.Context, nid int64) error { + argsMap["set_nid"] = func(ctx *gin.Context, nid int64) error { return _DefaultAccountPunishment.OpUpdate(ctx, &accountpunishmentproto.OpUpdateReq{ AccountPunishment: &dbstruct.AccountPunishment{ Id: acctpunishment.Id, diff --git a/app/mix/service/service.go b/app/mix/service/service.go index 997217af..7f59afe3 100644 --- a/app/mix/service/service.go +++ b/app/mix/service/service.go @@ -329,8 +329,8 @@ func (s *Service) ConnectToStreamerRecommService(r *StreamerRecommService) { } // 通知推送接口 -func (s *Service) ConnectToNotifCenter(connFunc func(*logic.Notification, *NotifBcstCenter)) { - connFunc(_DefaultNotification, DefaultNotifBcstCenter) +func (s *Service) ConnectToNotifCenter(connFunc func(*logic.Notification, *logic.NotifBcstVers, *NotifBcstCenter)) { + connFunc(_DefaultNotification, _DefaultNotifBcstVers, DefaultNotifBcstCenter) } // Product @@ -2324,7 +2324,7 @@ func (s *Service) OpApproveStreamerAuthApprovalDetails(ctx *gin.Context, req *st } // 发送通知 - DefaultNotifBuilderHandler.Handle(ctx, consts.SysNotifTemp_StreamerAuthApprovalPassed, mids) + DefaultNotifBuilderHandler.Handle(ctx)(consts.SysNotifTemp_StreamerAuthApprovalPassed)(mids) } return @@ -3777,7 +3777,8 @@ func (s *Service) OpCreateAccountPunishment(ctx *gin.Context, req *accountpunish } // 封禁通知 - DefaultNotifBuilderHandler.Handle(ctx, consts.SysNotifTemp_StreamerPunished, req.AccountPunishment) + DefaultNotifBuilderHandler.Handle(ctx)( + consts.SysNotifTemp_StreamerPunished, consts.SysNotifTemp_StreamerPunishmentEnds)(req.AccountPunishment) return } @@ -3818,7 +3819,7 @@ func (s *Service) OpUnblockAccountPunishment(ctx *gin.Context, req *accountpunis ec = errcode.ErrCodeAccountPunishmentSrvFail return } - DefaultNotifBuilderHandler.Handle(ctx, consts.SysNotifTemp_CancelNotif, acctpunishment) + DefaultNotifBuilderHandler.Handle(ctx)(consts.SysNotifTemp_CancelNotif)(acctpunishment) return } diff --git a/app/mix/service/utilservice.go b/app/mix/service/utilservice.go index ed4dd088..e8302f09 100644 --- a/app/mix/service/utilservice.go +++ b/app/mix/service/utilservice.go @@ -2189,7 +2189,7 @@ func (s *Service) utilWriteNotifInfoByMap(ctx *gin.Context, notifTempId int64, o notifBuilder.PushTime = pushTimeObj.(int64) } - setNidObj, ok := mp["nid_save_func"] + setNidObj, ok := mp["set_nid"] if ok { notifBuilder.SetNid = setNidObj.(func(ctx *gin.Context, nid int64) error) } diff --git a/library/middleware/notif_sender.go b/library/middleware/notif_sender.go index f31f1d33..f4e0de14 100644 --- a/library/middleware/notif_sender.go +++ b/library/middleware/notif_sender.go @@ -21,7 +21,7 @@ var ( DefaultNotifSender gin.HandlerFunc ) -func InitNotifSender(_DefaultNotification *logic.Notification, _DefaultNotifBcstCenter *service.NotifBcstCenter) { +func InitNotifSender(_DefaultNotification *logic.Notification, _DefaultNotifBcstVers *logic.NotifBcstVers, _DefaultNotifBcstCenter *service.NotifBcstCenter) { DefaultNotifSender = func(ctx *gin.Context) { // 获取通知builder @@ -34,59 +34,22 @@ func InitNotifSender(_DefaultNotification *logic.Notification, _DefaultNotifBcst for _, notifBuilder := range notifBuilders { // 如果是取消推送,则更新推送状态为已取消 - if notifBuilder.TemplateId == consts.SysNotifTemp_CancelNotif { - err := _DefaultNotification.OpUpdate(ctx, ¬ificationproto.OpUpdateReq{ - Notification: &dbstruct.Notification{ - Id: goproto.Int64(notifBuilder.GetNid()), - Status: goproto.Int64(consts.Notification_Cancelled), - }, - }) - if err != nil { - logger.Error("_DefaultNotification OpUpdate failed : %v", err) - } + if CancelNotif(ctx, notifBuilder, _DefaultNotification) { continue } - notification := &dbstruct.Notification{} - notification.SubMid = goproto.Int64(0) + // 如果是同步广播版本号,则进行同步 + if SyncNotifBcstVers(ctx, notifBuilder, _DefaultNotifBcstVers) { + continue + } - // 从模板Id拿到模板信息 - key := fmt.Sprint(notifBuilder.TemplateId) - cfg := apollostruct.NotifTemplateCfg{} - err := apollo.GetJson(key, &cfg, apollo.ApolloOpts().SetNamespace("notif_template")) + // 组装通知 + notification, err := AssembleNotification(notifBuilder) if err != nil { - logger.Error("Apollo read failed : %v", err) + logger.Error("通知组装失败:%v", err) continue } - // 通知接收人mids不为空则默认认为是自定义发送 - if len(notifBuilder.ObjMids) > 0 { - notification.ObjMids = notifBuilder.ObjMids - notification.ObjType = goproto.Int64(consts.Notification_ObjType_Customized) - } else { - notification.ObjType = goproto.Int64(notifBuilder.ObjType) - } - - // 消息类型 - notification.NType = goproto.Int64(cfg.NType) - notification.NDesc = goproto.String(consts.NotifDescMap[cfg.NType]) - - // 拼装通知信息 - msg := fmt.Sprintf(cfg.NotifTemplate, notifBuilder.TemplateParams...) - notification.Message = goproto.String(msg) - - // 链接信息 - if notifBuilder.Action != "" { - linkText := fmt.Sprintf(cfg.LinkTextTemplate, notifBuilder.LinkTextTemplateParams...) - notification.LinkText = goproto.String(linkText) - notification.Action = goproto.String(notifBuilder.Action) - notification.Thumbnail = notifBuilder.Thumbnail - notification.Params = goproto.String(notifBuilder.Params) - } - - // 推送时间 - notification.PushTime = goproto.Int64(notifBuilder.PushTime) - // 创建通知 err = _DefaultNotification.OpCreate(ctx, ¬ificationproto.OpCreateReq{ Notification: notification, @@ -125,3 +88,97 @@ func InitNotifSender(_DefaultNotification *logic.Notification, _DefaultNotifBcst func NotifSender() gin.HandlerFunc { return DefaultNotifSender } + +func CancelNotif(ctx *gin.Context, notifBuilder *dbstruct.NotifBuilder, notifService *logic.Notification) bool { + if notifBuilder.TemplateId == consts.SysNotifTemp_CancelNotif { + err := notifService.OpUpdate(ctx, ¬ificationproto.OpUpdateReq{ + Notification: &dbstruct.Notification{ + Id: goproto.Int64(notifBuilder.GetNid()), + Status: goproto.Int64(consts.Notification_Cancelled), + }, + }) + if err != nil { + logger.Error("_DefaultNotification OpUpdate failed : %v", err) + } + return true + } + return false +} + +func SyncNotifBcstVers(ctx *gin.Context, notifBuilder *dbstruct.NotifBuilder, notifBcstVersService *logic.NotifBcstVers) bool { + + objType := int64(-1) + if notifBuilder.TemplateId == consts.SysNotifTemp_SyncNotifBcstVersForUser { + objType = consts.Notification_ObjType_AllUser + + } else if notifBuilder.TemplateId == consts.SysNotifTemp_SyncNotifBcstVersForStreamer { + objType = consts.Notification_ObjType_AllStreamer + } + + if objType != -1 { + // 获取当前主播/用户全局广播的版本号(注意这个版本号-1才是当前数据库有的最新版本号) + notifBcstVers, err := notifBcstVersService.GetNotifBcstVers(ctx, objType) + if err != nil { + logger.Error("GetNotifBcstVers fail, err: %v", err) + return true + } + + // 获取该主播/用户已接收的全局广播版本号,并直接更新至最新的全局广播版本号 + for _, mid := range notifBuilder.ObjMids { + _, err = notifBcstVersService.GetAndUpdateNotifBcstReceiveVers(ctx, mid, notifBcstVers.Vers) + if err != nil { + logger.Error("GetAndUpdateNotifBcstReceiveVers fail, err: %v", err) + return true + } + } + + return true + } else { + return false + } + +} + +func AssembleNotification(notifBuilder *dbstruct.NotifBuilder) (*dbstruct.Notification, error) { + notification := &dbstruct.Notification{} + notification.SubMid = goproto.Int64(0) + + // 从模板Id拿到模板信息 + key := fmt.Sprint(notifBuilder.TemplateId) + cfg := apollostruct.NotifTemplateCfg{} + err := apollo.GetJson(key, &cfg, apollo.ApolloOpts().SetNamespace("notif_template")) + if err != nil { + logger.Error("Apollo read failed : %v", err) + return nil, err + } + + // 通知接收人mids不为空则默认认为是自定义发送 + if len(notifBuilder.ObjMids) > 0 { + notification.ObjMids = notifBuilder.ObjMids + notification.ObjType = goproto.Int64(consts.Notification_ObjType_Customized) + } else { + notification.ObjType = goproto.Int64(notifBuilder.ObjType) + } + + // 消息类型 + notification.NType = goproto.Int64(cfg.NType) + notification.NDesc = goproto.String(consts.NotifDescMap[cfg.NType]) + + // 拼装通知信息 + msg := fmt.Sprintf(cfg.NotifTemplate, notifBuilder.TemplateParams...) + notification.Message = goproto.String(msg) + + // 链接信息 + if notifBuilder.Action != "" { + linkText := fmt.Sprintf(cfg.LinkTextTemplate, notifBuilder.LinkTextTemplateParams...) + notification.LinkText = goproto.String(linkText) + notification.Action = goproto.String(notifBuilder.Action) + notification.Thumbnail = notifBuilder.Thumbnail + notification.Params = goproto.String(notifBuilder.Params) + } + + // 推送时间 + notification.PushTime = goproto.Int64(notifBuilder.PushTime) + + return notification, nil +}