package infmtser import ( "sort" "time" "91porn-server/models/v/noticefmtmod" "91porn-server/models/v/noticerecdmod" "91porn-server/models/v/usermod" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" ) // ObjectID type ObjectID = primitive.ObjectID type Sender = noticefmtmod.Sender type NoticeFmt = noticefmtmod.NoticeFmt type Notice struct { SendAt time.Time `json:"sendAt"` //消息的发送时间 Sender Sender `json:"sender"` //发送者 Title string `json:"title"` //标题 Content string `json:"content"` //内容 } // 通知预览 type NoticPreview struct { NewsCount int64 `json:"newsCount"` Notice } type FMTEnableMatch = noticefmtmod.EnableMatch func UpdateNoticePreviewList(uid uint64, curTime time.Time) ([]NoticPreview, bool, error) { enable := true enableMatch := FMTEnableMatch{Enable: &enable} noticeFmts, err := noticefmtmod.GetNoticeFmtListByUID(uid, enableMatch.New()) if err != nil { return nil, false, err } noticeFmtsLen := len(noticeFmts) var ( noticeCodeList = make([]string, noticeFmtsLen) noticeFmtMap = make(map[string]NoticeFmt) systemNoticeCodeList = make([]string, 0, noticeFmtsLen) actAsstNoticeCodeList = make([]string, 0, noticeFmtsLen) ) for i, n := range noticeFmts { sender := n.Sender if sender == noticefmtmod.System { systemNoticeCodeList = append(systemNoticeCodeList, n.NoticeCode) } else if sender == noticefmtmod.ActAsst { actAsstNoticeCodeList = append(actAsstNoticeCodeList, n.NoticeCode) } noticeFmtMap[n.NoticeCode] = n noticeCodeList[i] = n.NoticeCode } lastSendAtMap, err := noticerecdmod.GetLastSendAtMap(uid, noticeCodeList) if err != nil { return nil, false, err } var nextSendAtMap = make(map[string]time.Time) //新通知 for _, fmt := range noticeFmts { nextSendTimeList := noticefmtmod.TimeSlice{} switch fmt.NoticeType { case noticefmtmod.MailNoticeType: nextSendTimeList = fmt.MailNotice.NextSendTimeList(curTime, lastSendAtMap[fmt.NoticeCode]) case noticefmtmod.RegularNoticeType: nextSendTimeList = fmt.RegularNotice.NextSendTimeList(curTime, lastSendAtMap[fmt.NoticeCode]) case noticefmtmod.PlanNoticeType: nextSendTimeList = fmt.PlanNotice.NextSendTimeList(curTime, lastSendAtMap[fmt.NoticeCode]) case noticefmtmod.SpecifyNoticeType: nextSendTimeList = fmt.SpecifyNotice.NextSendTimeList(curTime, lastSendAtMap[fmt.NoticeCode]) case noticefmtmod.AfterRegistNoticeType: user, _ := usermod.FindUserByUID(uid) if user != nil { afterRegistNoticeEx := noticefmtmod.AfterRegistNoticeEx{AfterRegistNotice: fmt.AfterRegistNotice, CreatedAt: user.CreatedAt} nextSendTimeList = afterRegistNoticeEx.NextSendTimeList(curTime, lastSendAtMap[fmt.NoticeCode]) } } if nextSendTimeList.Len() != 0 { nextSendAtMap[fmt.NoticeCode] = nextSendTimeList[0] } } if err = noticerecdmod.UpsertLastSendAt(uid, nextSendAtMap); err != nil { return nil, false, err } return getNoticePreview(uid, noticeFmtMap, systemNoticeCodeList, actAsstNoticeCodeList) } func getNoticePreview(uid uint64, noticeFmtMap map[string]NoticeFmt, systemNoticeCodeList []string, actAsstNoticeCodeList []string) ([]NoticPreview, bool, error) { sysRecordSlice, err := noticerecdmod.GetRecordSlice(uid, systemNoticeCodeList) if err != nil { return nil, false, err } astRecordSlice, err := noticerecdmod.GetRecordSlice(uid, actAsstNoticeCodeList) if err != nil { return nil, false, err } var noticTalkList []NoticPreview totalHasNew := false fill := func(recordSlice noticerecdmod.RecordSlice) { if recordSlice.Len() == 0 { return } sort.Sort(sort.Reverse(recordSlice)) //发送时间降序 top := recordSlice[0] noticeFmt, ok := noticeFmtMap[top.NoticeCode] if !ok { return } notice := Notice{ SendAt: top.LastSendAt, Sender: noticeFmt.Sender, Title: noticeFmt.Title, Content: noticeFmt.Content, } newsCount := int64(0) for _, v := range recordSlice { if v.LastSendAt.After(v.LastReadAt) { newsCount++ } } totalHasNew = totalHasNew || (newsCount > 0) noticTalkList = append(noticTalkList, NoticPreview{newsCount, notice}) } fill(sysRecordSlice) fill(astRecordSlice) return noticTalkList, totalHasNew, nil } type NoticePage struct { HasNext bool `json:"hasNext"` List []Notice `json:"list"` } type FMTSenderMatch = noticefmtmod.SenderMatch type RecdNoticeCodeInMatch = noticerecdmod.NoticeCodeInMatch type RecdUIDMatch = noticerecdmod.UIDMatch func NoticePages(sender Sender, uid uint64, skip int64, limit int64) (NoticePage, error) { enable := true enableMatch := FMTEnableMatch{Enable: &enable} senderMatch := FMTSenderMatch{Sender: &sender} noticeFmts, err := noticefmtmod.GetNoticeFmtListByUID(uid, senderMatch.New(), enableMatch.New()) if err != nil { return NoticePage{}, err } noticeCodeList := make([]string, len(noticeFmts)) fmtMap := make(map[string]NoticeFmt) for i, fmt := range noticeFmts { noticeCodeList[i] = fmt.NoticeCode fmtMap[fmt.NoticeCode] = fmt } sort := bson.D{{Key: "lastSendAt", Value: -1}} recdNoticeCodeInMatch := RecdNoticeCodeInMatch{NoticeCodes: noticeCodeList} recdUIDMatch := RecdUIDMatch{UID: &uid} limitEx := limit + 1 list, err := noticerecdmod.List(sort, skip, limitEx, recdUIDMatch.New(), recdNoticeCodeInMatch.New()) if err != nil { return NoticePage{}, err } hasNext := false if len(list) > int(limit) { hasNext = true list = list[:limit] } noticeList := make([]Notice, 0, list.Len()) for _, v := range list { noticeCode := v.NoticeCode fmt, ok := fmtMap[noticeCode] if !ok { continue } notice := Notice{ SendAt: v.LastSendAt, Sender: fmt.Sender, Title: fmt.Title, Content: fmt.Content, } noticeList = append(noticeList, notice) } return NoticePage{ hasNext, noticeList, }, nil } func UpdateNoticeReadTime(sender Sender, uid uint64, readAt time.Time) error { senderMatch := FMTSenderMatch{Sender: &sender} noticeFmts, err := noticefmtmod.GetNoticeFmtListByUID(uid, senderMatch.New()) if err != nil { return err } noticeCodeList := make([]string, len(noticeFmts)) for i, fmt := range noticeFmts { noticeCodeList[i] = fmt.NoticeCode } return noticerecdmod.UpdateReadTime(readAt, uid, noticeCodeList) } const ( Fans = noticerecdmod.Fans //粉丝 Like = noticerecdmod.Like //点赞 Cmet = noticerecdmod.Cmet //评论 Itte = noticerecdmod.Itte //互动 ) // 动态预览 type TrendPreview struct { Count int64 `json:"count"` //数量 } // 动态预览映射 func TrendPreviewMap(uid uint64) (map[noticerecdmod.TrendType]TrendPreview, bool) { var ( fensPreviewCount int64 //粉丝预览数 likePreviewCount int64 //点赞预览数 cmetPreviewCount int64 //评论预览数 ittePreviewCount int64 //互动预览数 暂不做 ) hasNews := (fensPreviewCount + likePreviewCount + cmetPreviewCount + ittePreviewCount) > 0 return map[noticerecdmod.TrendType]TrendPreview{ Fans: {fensPreviewCount}, Like: {likePreviewCount}, Cmet: {cmetPreviewCount}, Itte: {ittePreviewCount}, }, hasNews }