185 lines
5.3 KiB
Go
185 lines
5.3 KiB
Go
package middleware
|
||
|
||
import (
|
||
"fmt"
|
||
"service/apollostruct"
|
||
"service/app/mix/service"
|
||
"service/app/mix/service/logic"
|
||
"service/dbstruct"
|
||
"service/library/apollo"
|
||
"service/library/logger"
|
||
|
||
"service/api/consts"
|
||
notificationproto "service/api/proto/notification/proto"
|
||
|
||
goproto "google.golang.org/protobuf/proto"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
var (
|
||
DefaultNotifSender gin.HandlerFunc
|
||
)
|
||
|
||
func InitNotifSender(_DefaultNotification *logic.Notification, _DefaultNotifBcstVers *logic.NotifBcstVers, _DefaultNotifBcstCenter *service.NotifBcstCenter) {
|
||
DefaultNotifSender = func(ctx *gin.Context) {
|
||
|
||
// 获取通知builder
|
||
notifBuildersObj, ok := ctx.Get("notif_builders")
|
||
if !ok {
|
||
return
|
||
}
|
||
notifBuilders := notifBuildersObj.([]*dbstruct.NotifBuilder)
|
||
|
||
for _, notifBuilder := range notifBuilders {
|
||
|
||
// 如果是取消推送,则更新推送状态为已取消
|
||
if CancelNotif(ctx, notifBuilder, _DefaultNotification) {
|
||
continue
|
||
}
|
||
|
||
// 如果是同步广播版本号,则进行同步
|
||
if SyncNotifBcstVers(ctx, notifBuilder, _DefaultNotifBcstVers) {
|
||
continue
|
||
}
|
||
|
||
// 组装通知
|
||
notification, err := AssembleNotification(notifBuilder)
|
||
if err != nil {
|
||
logger.Error("通知组装失败:%v", err)
|
||
continue
|
||
}
|
||
|
||
// 创建通知
|
||
err = _DefaultNotification.OpCreate(ctx, ¬ificationproto.OpCreateReq{
|
||
Notification: notification,
|
||
})
|
||
if err != nil {
|
||
logger.Error("通知创建失败:%v", err)
|
||
continue
|
||
}
|
||
|
||
// 将通知id暂存,若暂存失败,则不广播该条通知,因业务无法再控制其停止
|
||
if notifBuilder.SetNid != nil {
|
||
err = notifBuilder.SetNid(ctx, notification.GetId())
|
||
if err != nil {
|
||
logger.Error("通知id暂存失败:%v", err)
|
||
continue
|
||
}
|
||
}
|
||
|
||
nids := make([]int64, 0)
|
||
nids = append(nids, notification.GetId())
|
||
|
||
// 广播通知
|
||
if notification.GetPushTime() == consts.Notification_PushTime_Instant {
|
||
err = _DefaultNotifBcstCenter.BcstNotifs(ctx, nids, notification.GetObjType(), notification.ObjMids)
|
||
if err != nil {
|
||
logger.Error("通知广播失败:%v", err)
|
||
continue
|
||
}
|
||
}
|
||
}
|
||
|
||
ctx.Next()
|
||
}
|
||
}
|
||
|
||
func NotifSender() gin.HandlerFunc {
|
||
return DefaultNotifSender
|
||
}
|
||
|
||
func CancelNotif(ctx *gin.Context, notifBuilder *dbstruct.NotifBuilder, notifService *logic.Notification) bool {
|
||
if notifBuilder.TemplateId == consts.CtrlNotifTemp_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.CtrlNotifTemp_SyncNotifBcstVersForUser {
|
||
objType = consts.Notification_ObjType_AllUser
|
||
|
||
} else if notifBuilder.TemplateId == consts.CtrlNotifTemp_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
|
||
}
|