by Robin at 20241107
This commit is contained in:
parent
521d7694c2
commit
9b830999aa
|
@ -66,6 +66,7 @@ const (
|
|||
DefaultZoneTextKey = "default_zone_text"
|
||||
AuditTaskCollectionReflectKey = "audit_task_collection_reflect"
|
||||
NotifBannerInfoKey = "notif_banner_info"
|
||||
AcctPunishmentRealEndTimeKey = "acct_punishment_real_endtime"
|
||||
)
|
||||
|
||||
// del_flag
|
||||
|
|
|
@ -7,8 +7,8 @@ const (
|
|||
Notif_Audit = 1 // 审核消息
|
||||
Notif_Vas = 2 // 付费消息
|
||||
)
|
||||
|
||||
const (
|
||||
SysNotifTemp_CancelNotif = -1 // 取消推送通知
|
||||
SysNotifTemp_FirstLogin = 1 // 首次登录
|
||||
SysNotifTemp_StreamerPunished = 2 // 主播封禁
|
||||
SysNotifTemp_StreamerPunishmentEnds = 3 // 主播封禁结束
|
||||
|
|
|
@ -185,6 +185,7 @@ var ErrCodeMsgMap = map[ErrCode]string{
|
|||
ErrCodeAccountPunishmentHasFinished: "账号处罚已正常结束,无法执行该操作!",
|
||||
ErrCodeAccountPunishmentHasBeenInterrupted: "账号处罚已提前中止,无法执行该操作!",
|
||||
ErrCodeAccountPunishmentStreamerOnly: "该账号处罚行为仅能对主播进行!",
|
||||
ErrCodeAccountPunishmentEndTimeCalcFail: "账号处罚结束时间计算错误",
|
||||
|
||||
ErrCodeAccountCancellationSrvFail: "账户注销服务错误",
|
||||
ErrCodeAccountCancellationNotExist: "账户注销不存在",
|
||||
|
@ -518,6 +519,7 @@ const (
|
|||
ErrCodeAccountPunishmentHasFinished ErrCode = -32005 // 账号处罚已正常结束
|
||||
ErrCodeAccountPunishmentHasBeenInterrupted ErrCode = -32006 // 账号处罚已提前中止
|
||||
ErrCodeAccountPunishmentStreamerOnly ErrCode = -32007 // 该账号处罚仅能对主播进行
|
||||
ErrCodeAccountPunishmentEndTimeCalcFail ErrCode = -32008 // 账号处罚结束时间计算错误
|
||||
|
||||
// Zone: 33xxx
|
||||
ErrCodeZoneSrvOk ErrCode = ErrCodeOk
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package interfaces
|
||||
|
||||
type NidAccessible interface {
|
||||
GetNid() int64
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package apollostruct
|
||||
|
||||
// 账号处罚结束实际生效时间配置,用于通知推送服务
|
||||
|
||||
/* 在账号处罚创建时,除了立即给用户推送一条封禁通知,还会写一条解禁通知,推送时间为处罚的结束时间
|
||||
正常来说,账号处罚结束时间 = 账号处罚创建时间 + 触发时长
|
||||
但由于具体场景存在的时延,在上述计算得到的账号处罚的结束时间,处罚可能还未结束
|
||||
如主播推荐列表每1个小时推送一次,故它实际生效时间应该是结束时间顺延的下一个小时整点
|
||||
动态推荐列表每5分钟推送一次,故它实际生效时间应该是结束时间顺延的下一个5分整点*/
|
||||
|
||||
/* 我们认为用户实际感知到的处罚结束应该在他收到通知的时候,所以解禁的通知时间需要根据具体场景延后一些
|
||||
interval_map表示具体场景的定时任务每隔多少时间执行一次,单位为秒
|
||||
比如对于主播推荐列表,时间间隔就是3600秒,解禁通知的时间戳需要补足至3600秒的倍数
|
||||
*/
|
||||
|
||||
/*
|
||||
default_interval表示推送“定时通知”的定时任务的时间间隔
|
||||
如果这条封禁的场景没有定时推送的需求,则解禁通知的时间戳补足至default_interval的倍数即可
|
||||
用以满足“用户实际感知到的处罚结束应该在他收到通知的时候”
|
||||
需要注意,interval_map每个键值对的值必须是default_interval的倍数,否则推送通知会产生异常
|
||||
*/
|
||||
|
||||
type AcctPunishmentRealEndtimeCfg struct {
|
||||
IntervalMap map[string]int64 `json:"interval_map"` // 时间间隔map
|
||||
DefaultInterval int64 `json:"default_interval"` // 默认通知时间间隔
|
||||
}
|
|
@ -4,7 +4,6 @@ import (
|
|||
"service/api/consts"
|
||||
accountpunishmentproto "service/api/proto/accountpunishment/proto"
|
||||
"service/app/mix/dao"
|
||||
"service/bizcommon/util"
|
||||
"service/dbstruct"
|
||||
"service/library/logger"
|
||||
"time"
|
||||
|
@ -36,7 +35,6 @@ func (p *AccountPunishment) OpCreate(ctx *gin.Context, req *accountpunishmentpro
|
|||
nowTime := time.Now().Unix()
|
||||
req.AccountPunishment.Id = goproto.Int64(accountpunishmentIdSeq.Seq)
|
||||
req.AccountPunishment.Status = goproto.Int64(consts.AccountPunishment_Punishing)
|
||||
req.AccountPunishment.EndTime = goproto.Int64(nowTime + util.DerefInt64(req.Duration))
|
||||
req.AccountPunishment.Ct = goproto.Int64(nowTime)
|
||||
req.AccountPunishment.Ut = goproto.Int64(nowTime)
|
||||
req.AccountPunishment.DelFlag = goproto.Int64(consts.Exist)
|
||||
|
|
|
@ -2,12 +2,15 @@ package service
|
|||
|
||||
import (
|
||||
"service/api/consts"
|
||||
"service/api/interfaces"
|
||||
accountpunishmentproto "service/api/proto/accountpunishment/proto"
|
||||
zoneproto "service/api/proto/zone/proto"
|
||||
"service/bizcommon/util"
|
||||
"service/dbstruct"
|
||||
"service/library/logger"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
goproto "google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
var DefaultNotifBuilderHandler *NotifBuilderHandler
|
||||
|
@ -28,6 +31,7 @@ func NewNotifBuilderHandler() *NotifBuilderHandler {
|
|||
}
|
||||
|
||||
func (handler *NotifBuilderHandler) init() {
|
||||
handler.handleSysNotifCancelNotif()
|
||||
handler.handleSysFirstLogin()
|
||||
handler.handleSysStreamerPunished()
|
||||
handler.handleSysPswdChanged()
|
||||
|
@ -38,6 +42,13 @@ func (handler *NotifBuilderHandler) init() {
|
|||
handler.handleSysZoneThirdPartnerCreated()
|
||||
}
|
||||
|
||||
func (handler *NotifBuilderHandler) handleSysNotifCancelNotif() {
|
||||
handler.handlerMap[consts.SysNotifTemp_CancelNotif] = func(ctx *gin.Context, args ...any) {
|
||||
nidAccessor := args[0].(interfaces.NidAccessible)
|
||||
DefaultService.utilWriteNotifCancel(ctx, nidAccessor)
|
||||
}
|
||||
}
|
||||
|
||||
func (handler *NotifBuilderHandler) handleSysFirstLogin() {
|
||||
handler.handlerMap[consts.SysNotifTemp_FirstLogin] = func(ctx *gin.Context, args ...any) {
|
||||
account := args[0].(*dbstruct.Account)
|
||||
|
@ -53,7 +64,17 @@ func (handler *NotifBuilderHandler) handleSysStreamerPunished() {
|
|||
consts.AccountPunishmentMap[acctpunishment.GetType()], util.FormatTsAsNotifT(acctpunishment.GetEndTime()))
|
||||
// 解禁通知
|
||||
if !acctpunishment.IsPermanent() {
|
||||
DefaultService.utilWriteCrontabNotifInfo(ctx, consts.SysNotifTemp_StreamerPunishmentEnds, acctpunishment.GetMid(), acctpunishment.GetEndTime())
|
||||
argsMap := make(map[string]any)
|
||||
argsMap["push_time"] = acctpunishment.GetEndTime()
|
||||
argsMap["nid_save_func"] = func(ctx *gin.Context, nid int64) error {
|
||||
return _DefaultAccountPunishment.OpUpdate(ctx, &accountpunishmentproto.OpUpdateReq{
|
||||
AccountPunishment: &dbstruct.AccountPunishment{
|
||||
Id: acctpunishment.Id,
|
||||
Nid: goproto.Int64(nid),
|
||||
},
|
||||
})
|
||||
}
|
||||
DefaultService.utilWriteNotifInfoByMap(ctx, consts.SysNotifTemp_StreamerPunishmentEnds, acctpunishment.GetMid(), argsMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3754,7 +3754,17 @@ func (s *Service) OpCreateAccountPunishment(ctx *gin.Context, req *accountpunish
|
|||
return
|
||||
}
|
||||
|
||||
err := _DefaultAccountPunishment.OpCreate(ctx, req)
|
||||
// 计算处罚结束的通知时间
|
||||
req.AccountPunishment.EndTime = goproto.Int64(time.Now().Unix() + util.DerefInt64(req.Duration))
|
||||
realEndTime, err := s.utilCalcAccountPunishmentEndNotifTime(req.AccountPunishment)
|
||||
if err != nil {
|
||||
logger.Error("utilCalcAccountPunishmentEndNotifTime fail, req: %v, err: %v", util.ToJson(req), err)
|
||||
ec = errcode.ErrCodeAccountPunishmentSrvFail
|
||||
return
|
||||
}
|
||||
req.AccountPunishment.EndTime = goproto.Int64(realEndTime)
|
||||
|
||||
err = _DefaultAccountPunishment.OpCreate(ctx, req)
|
||||
if err != nil {
|
||||
logger.Error("OpCreate fail, req: %v, err: %v", util.ToJson(req), err)
|
||||
ec = errcode.ErrCodeAccountPunishmentSrvFail
|
||||
|
@ -3790,6 +3800,21 @@ func (s *Service) OpUnblockAccountPunishment(ctx *gin.Context, req *accountpunis
|
|||
ec = errcode.ErrCodeAccountPunishmentSrvFail
|
||||
return
|
||||
}
|
||||
|
||||
// 取消该条推送
|
||||
acctpunishment, err := _DefaultAccountPunishment.OpListById(ctx, util.DerefInt64(req.Id))
|
||||
if err == qmgo.ErrNoSuchDocuments {
|
||||
ec = errcode.ErrCodeAccountPunishmentNotExist
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
logger.Error("OpListById fail, req: %v, err: %v", util.ToJson(req), err)
|
||||
ec = errcode.ErrCodeAccountPunishmentSrvFail
|
||||
return
|
||||
}
|
||||
DefaultNotifBuilderHandler.Handle(ctx, consts.SysNotifTemp_CancelNotif, acctpunishment)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -2116,6 +2116,21 @@ func (s *Service) UtilEncryptVideosForZoneMomentVOs(ctx *gin.Context, list []*zo
|
|||
}
|
||||
}
|
||||
|
||||
func (s *Service) utilWriteNotifCancel(ctx *gin.Context, nidAccessor interfaces.NidAccessible) {
|
||||
// 获取通知builder
|
||||
notifBuilders := make([]*dbstruct.NotifBuilder, 0)
|
||||
notifBuildersObj, ok := ctx.Get("notif_builders")
|
||||
if ok {
|
||||
notifBuilders = notifBuildersObj.([]*dbstruct.NotifBuilder)
|
||||
}
|
||||
|
||||
notifBuilders = append(notifBuilders, &dbstruct.NotifBuilder{
|
||||
TemplateId: consts.SysNotifTemp_CancelNotif,
|
||||
NidGetter: nidAccessor.GetNid,
|
||||
})
|
||||
ctx.Set("notif_builders", notifBuilders)
|
||||
}
|
||||
|
||||
func (s *Service) utilWriteNotifInfo(ctx *gin.Context, notifTempId int64, objMid int64, notifTempParams ...any) {
|
||||
// 获取通知builder
|
||||
notifBuilders := make([]*dbstruct.NotifBuilder, 0)
|
||||
|
@ -2132,23 +2147,6 @@ func (s *Service) utilWriteNotifInfo(ctx *gin.Context, notifTempId int64, objMid
|
|||
ctx.Set("notif_builders", notifBuilders)
|
||||
}
|
||||
|
||||
func (s *Service) utilWriteCrontabNotifInfo(ctx *gin.Context, notifTempId int64, objMid int64, pushTime int64, notifTempParams ...any) {
|
||||
// 获取通知builder
|
||||
notifBuilders := make([]*dbstruct.NotifBuilder, 0)
|
||||
notifBuildersObj, ok := ctx.Get("notif_builders")
|
||||
if ok {
|
||||
notifBuilders = notifBuildersObj.([]*dbstruct.NotifBuilder)
|
||||
}
|
||||
|
||||
notifBuilders = append(notifBuilders, &dbstruct.NotifBuilder{
|
||||
TemplateId: notifTempId,
|
||||
ObjMids: []int64{objMid},
|
||||
PushTime: pushTime,
|
||||
TemplateParams: notifTempParams,
|
||||
})
|
||||
ctx.Set("notif_builders", notifBuilders)
|
||||
}
|
||||
|
||||
func (s *Service) utilWriteNotifInfoByMap(ctx *gin.Context, notifTempId int64, objMid int64, mp map[string]any) {
|
||||
// 获取通知builder
|
||||
notifBuilders := make([]*dbstruct.NotifBuilder, 0)
|
||||
|
@ -2191,6 +2189,32 @@ func (s *Service) utilWriteNotifInfoByMap(ctx *gin.Context, notifTempId int64, o
|
|||
notifBuilder.PushTime = pushTimeObj.(int64)
|
||||
}
|
||||
|
||||
nidSaveFuncObj, ok := mp["nid_save_func"]
|
||||
if ok {
|
||||
notifBuilder.NidSaveFunc = nidSaveFuncObj.(func(ctx *gin.Context, nid int64) error)
|
||||
}
|
||||
|
||||
notifBuilders = append(notifBuilders, notifBuilder)
|
||||
ctx.Set("notif_builders", notifBuilders)
|
||||
}
|
||||
|
||||
func (s *Service) utilCalcAccountPunishmentEndNotifTime(acctpunishment *dbstruct.AccountPunishment) (int64, error) {
|
||||
|
||||
notifTime := acctpunishment.GetEndTime()
|
||||
|
||||
cfg := apollostruct.AcctPunishmentRealEndtimeCfg{}
|
||||
err := apollo.GetJson(consts.AcctPunishmentRealEndTimeKey, &cfg, apollo.ApolloOpts().SetNamespace("application"))
|
||||
if err != nil {
|
||||
logger.Error("Apollo read failed : %v", err)
|
||||
return 0, err
|
||||
}
|
||||
|
||||
interval, ok := cfg.IntervalMap[fmt.Sprint(acctpunishment.GetType())]
|
||||
if !ok {
|
||||
interval = cfg.DefaultInterval
|
||||
}
|
||||
if notifTime%interval != 0 { // 已经是倍数则不再顺延
|
||||
notifTime = (notifTime/interval + 1) * interval
|
||||
}
|
||||
return notifTime, nil
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ type AccountPunishment struct {
|
|||
Duration *int64 `json:"duration" bson:"duration"` // 处罚时长
|
||||
EndTime *int64 `json:"end_time" bson:"end_time"` // 处罚结束时间
|
||||
Status *int64 `json:"status" bson:"status"` // 处罚结果
|
||||
Nid *int64 `json:"nid" bson:"nid"` // 通知表id,用于控制推送
|
||||
Ct *int64 `json:"ct" bson:"ct"` // 创建时间
|
||||
Ut *int64 `json:"ut" bson:"ut"` // 更新时间
|
||||
DelFlag *int64 `json:"del_flag" bson:"del_flag"` // 删除标记
|
||||
|
@ -60,3 +61,10 @@ func (p *AccountPunishment) GetType() int64 {
|
|||
}
|
||||
return *p.Type
|
||||
}
|
||||
|
||||
func (p *AccountPunishment) GetNid() int64 {
|
||||
if p == nil || p.Nid == nil {
|
||||
return 0
|
||||
}
|
||||
return *p.Nid
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package dbstruct
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type Notification struct {
|
||||
Id *int64 `json:"id" bson:"_id"` // 系统通知表id
|
||||
SubMid *int64 `json:"sub_mid" bson:"sub_mid"` // 通知发送人mid
|
||||
|
@ -95,13 +99,15 @@ type NotifReceivePull struct {
|
|||
}
|
||||
|
||||
type NotifBuilder struct {
|
||||
TemplateId int64 // 模板id
|
||||
TemplateParams []any // 模板参数
|
||||
ObjMids []int64 // 目标Mids
|
||||
ObjType int64 // 目标类型
|
||||
LinkTextTemplateParams []any // 链接模板参数
|
||||
Thumbnail *MediaComponent // 缩略图
|
||||
Action string // 行为
|
||||
Params string // 行为参数
|
||||
PushTime int64 // 推送时间
|
||||
TemplateId int64 // 模板id
|
||||
TemplateParams []any // 模板参数
|
||||
ObjMids []int64 // 目标Mids
|
||||
ObjType int64 // 目标类型
|
||||
LinkTextTemplateParams []any // 链接模板参数
|
||||
Thumbnail *MediaComponent // 缩略图
|
||||
Action string // 行为
|
||||
Params string // 行为参数
|
||||
PushTime int64 // 推送时间
|
||||
NidSaveFunc func(ctx *gin.Context, nid int64) error // nid存储函数,一般用于取消推送
|
||||
NidGetter func() int64 // nid访问器
|
||||
}
|
||||
|
|
|
@ -32,6 +32,21 @@ func InitNotifSender(_DefaultNotification *logic.Notification, _DefaultNotifBcst
|
|||
notifBuilders := notifBuildersObj.([]*dbstruct.NotifBuilder)
|
||||
|
||||
for _, notifBuilder := range notifBuilders {
|
||||
|
||||
// 如果是取消推送,则更新推送状态为已取消
|
||||
if notifBuilder.TemplateId == consts.SysNotifTemp_CancelNotif {
|
||||
err := _DefaultNotification.OpUpdate(ctx, ¬ificationproto.OpUpdateReq{
|
||||
Notification: &dbstruct.Notification{
|
||||
Id: goproto.Int64(notifBuilder.NidGetter()),
|
||||
Status: goproto.Int64(consts.Notification_Cancelled),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
logger.Error("_DefaultNotification OpUpdate failed : %v", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
notification := &dbstruct.Notification{}
|
||||
notification.SubMid = goproto.Int64(0)
|
||||
|
||||
|
@ -80,6 +95,13 @@ func InitNotifSender(_DefaultNotification *logic.Notification, _DefaultNotifBcst
|
|||
ctx.Next()
|
||||
}
|
||||
|
||||
// 将通知id暂存,若暂存失败,则不广播该条通知,因业务无法再控制其停止
|
||||
err = notifBuilder.NidSaveFunc(ctx, notification.GetId())
|
||||
if err != nil {
|
||||
logger.Error("通知id暂存失败:%v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
nids := make([]int64, 0)
|
||||
nids = append(nids, notification.GetId())
|
||||
|
||||
|
|
Loading…
Reference in New Issue